Merge pull request #13 from TheSUPERCD/upstream-clone
Resolve remaining merge conflicts
This commit is contained in:
commit
634f8f5376
|
|
@ -254,6 +254,7 @@
|
|||
<ClCompile Include="..\src\verilog_netlist.c" />
|
||||
<ClCompile Include="..\src\vhdl_netlist.c" />
|
||||
<ClCompile Include="..\src\xinit.c" />
|
||||
<ClCompile Include="eval_expr.c" />
|
||||
<ClCompile Include="expandlabel.c" />
|
||||
<ClCompile Include="parselabel.c" />
|
||||
</ItemGroup>
|
||||
|
|
@ -261,6 +262,7 @@
|
|||
<ClInclude Include="..\src\cairo_jpg.h" />
|
||||
<ClInclude Include="..\src\xschem.h" />
|
||||
<ClInclude Include="config.h" />
|
||||
<ClInclude Include="eval_expr.h" />
|
||||
<ClInclude Include="expandlabel.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -284,6 +286,11 @@
|
|||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\src\eval_expr.y">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">bison -p kk -o eval_expr.c ..\src\eval_expr.y </Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">eval_expr.c</Outputs>
|
||||
</CustomBuild>
|
||||
<None Include="..\src\xschem.tcl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
|||
|
|
@ -254,6 +254,7 @@
|
|||
<ClCompile Include="..\src\verilog_netlist.c" />
|
||||
<ClCompile Include="..\src\vhdl_netlist.c" />
|
||||
<ClCompile Include="..\src\xinit.c" />
|
||||
<ClCompile Include="eval_expr.c" />
|
||||
<ClCompile Include="expandlabel.c" />
|
||||
<ClCompile Include="parselabel.c" />
|
||||
</ItemGroup>
|
||||
|
|
@ -261,6 +262,7 @@
|
|||
<ClInclude Include="..\src\cairo_jpg.h" />
|
||||
<ClInclude Include="..\src\xschem.h" />
|
||||
<ClInclude Include="config.h" />
|
||||
<ClInclude Include="eval_expr.h" />
|
||||
<ClInclude Include="expandlabel.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -284,6 +286,11 @@
|
|||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\src\eval_expr.y">
|
||||
<FileType>Document</FileType>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">bison -p kk -o eval_expr.c ..\src\eval_expr.y </Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">eval_expr.c</Outputs>
|
||||
</CustomBuild>
|
||||
<None Include="..\src\xschem.tcl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
|
|
|||
|
|
@ -250,10 +250,7 @@
|
|||
<Component Id="CMPPLACESYMPINS">
|
||||
<File Id="PLACESYMPINS" KeyPath="yes" Source="../../src/place_sym_pins.tcl" />
|
||||
</Component>
|
||||
<Component Id="CMPCREATESYMBOL">
|
||||
<File Id="CREATESYMBOL" KeyPath="yes" Source="../../src/create_symbol.tcl" />
|
||||
</Component>
|
||||
|
||||
|
||||
<Directory Id="SYSTEMLIBFOLDER" Name="systemlib">
|
||||
<Component Id="CMPSYSTEMLIBFONTSCH">
|
||||
<File Id="FONTSCH" KeyPath="yes" Source="../../src/systemlib/font.sch" />
|
||||
|
|
@ -374,7 +371,6 @@
|
|||
<ComponentRef Id="CMPTRADUCIAWK" />
|
||||
<ComponentRef Id="CMPPLACEPLINS" />
|
||||
<ComponentRef Id="CMPPLACESYMPINS" />
|
||||
<ComponentRef Id="CMPCREATESYMBOL" />
|
||||
<ComponentRef Id="CMPVERILOGAWK" />
|
||||
<ComponentRef Id="CMPVHDLAWK" />
|
||||
<ComponentRef Id="CMPXSCHEMHELP" />
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -293,6 +293,9 @@
|
|||
<Component Id="cmpC76DA8327344C4B4AB04EF665B72B736" Guid="{2ACADB68-D803-40D4-BCA3-ECA604ED7AE9}">
|
||||
<File Id="filCC0547DA9E32AACF4F88B5E7AD58DEC0" KeyPath="yes" Source="$(var.xschemLibrarySrcDir)\devices\sqwsource.sym" />
|
||||
</Component>
|
||||
<Component Id="cmp57911CE62A560E61564C339A78C10282" Guid="{62F8D0F6-D4FF-4255-8B5B-FC912F25C3BB}">
|
||||
<File Id="fil4085D9852FFDBCA1DA05DFA41B6B63A2" KeyPath="yes" Source="$(var.xschemLibrarySrcDir)\devices\stop.sym" />
|
||||
</Component>
|
||||
<Component Id="cmpA4CE7D272C69DDD6A95DF0D02AC0D3C0" Guid="{C1242779-E7D6-43A3-B210-D631DEFDF56B}">
|
||||
<File Id="filEB57C82FF4DA64043A496E5A9ABF6802" KeyPath="yes" Source="$(var.xschemLibrarySrcDir)\devices\switch.sym" />
|
||||
</Component>
|
||||
|
|
@ -457,6 +460,7 @@
|
|||
<ComponentRef Id="cmpC0CDD9987356F9D8308F1F96CAA35403" />
|
||||
<ComponentRef Id="cmp530072B273A8627AFC7F2E628B5116CE" />
|
||||
<ComponentRef Id="cmpC76DA8327344C4B4AB04EF665B72B736" />
|
||||
<ComponentRef Id="cmp57911CE62A560E61564C339A78C10282" />
|
||||
<ComponentRef Id="cmpA4CE7D272C69DDD6A95DF0D02AC0D3C0" />
|
||||
<ComponentRef Id="cmp92D378095B64443F3454801FDB1FBF50" />
|
||||
<ComponentRef Id="cmpB88C8475423DC9A430B279627C98B455" />
|
||||
|
|
|
|||
|
|
@ -171,8 +171,14 @@
|
|||
#### this is the default:
|
||||
# set initial_geometry {900x600}
|
||||
|
||||
#### initial geometry of load /save / insert component file selector
|
||||
# set file_dialog_default_geometry 800x600
|
||||
#### initial size of the load_file_dialog (the file selector) dialog box
|
||||
# set file_dialog_default_geometry 700x680+100+40
|
||||
#### load_file_dialog directory list (+ recent if shown) X width in pixels
|
||||
# set file_dialog_sp0 350
|
||||
#### load_file_dialog recent components list X width in pixels
|
||||
# set file_dialog_sp1 100
|
||||
#### load_file_dialog components list Y height in pixels
|
||||
# set file_dialog_v_sp0 420
|
||||
|
||||
#### display full path (1) or only name (0) for component directories. Default: 1
|
||||
# set load_file_dialog_fullpath 1
|
||||
|
|
@ -195,6 +201,11 @@
|
|||
#### default: 0
|
||||
# set persistent_command 1
|
||||
|
||||
#### if set to 0 users must click a point after hitting a command key
|
||||
#### like 'w(ire)', 'l(ine)' and so on.
|
||||
#### default is 1 (hitting the command key sets also the first point).
|
||||
# set infix_interface 0
|
||||
|
||||
#### if set to 1 allow click & drag objects in the schematic
|
||||
#### to move them without keyboard commands ('m')
|
||||
#### default: enabled (1)
|
||||
|
|
@ -256,8 +267,24 @@
|
|||
#### enable drawing crosshairs at mouse coordinates. Default: disabled (0)
|
||||
# set draw_crosshair 1
|
||||
|
||||
#### set crosshair layer; Default 3 (TEXTLAYER)
|
||||
# set crosshair_layer 3
|
||||
#### set crosshair layer; Default 8 (Yellow)
|
||||
# set crosshair_layer 8
|
||||
|
||||
#### set crosshair size; Default: 0 (full screen spanning crosshair)
|
||||
# set crosshair_size 5
|
||||
|
||||
#### enable drawing a diamond-shaped cursor at the closest circuit endpoint. Default: disabled (0)
|
||||
# set snap_cursor 1
|
||||
|
||||
#### set snap_cursor_size; Default: 6 (Diamond-shaped cursor that snaps to nearest circuit endpoint)
|
||||
# set snap_cursor_size 6
|
||||
|
||||
#### set cadence_compat; Default: 0 (Cadence-style keybinds are not used by default)
|
||||
# set cadence_compat 1
|
||||
|
||||
#### if set, then, when cursor (regardless of style) is on an object, and user clicks (though mouse pointer is not on the object),
|
||||
#### the object is selected. Default: 0
|
||||
# set use_cursor_for_selection 1
|
||||
|
||||
#### enable to scale grid point size as done with lines at close zoom, default: 0
|
||||
# set big_grid_points 0
|
||||
|
|
@ -510,7 +537,10 @@ set editor {notepad.exe}
|
|||
# }
|
||||
# }
|
||||
|
||||
|
||||
###########################################################################
|
||||
#### TCL COMMANDS TO BE EXECUTED AFTER GENERATING NETLIST
|
||||
###########################################################################
|
||||
# set netlist_postprocess {textfile $netlist_dir/[xschem get netlist_name fallback]}
|
||||
|
||||
###########################################################################
|
||||
#### WEB URL DOWNLOAD HELPER APPLICATION
|
||||
|
|
@ -553,6 +583,14 @@ set editor {notepad.exe}
|
|||
#### default: 0 (not set)
|
||||
# set show_hidden_texts 1
|
||||
|
||||
###########################################################################
|
||||
#### USE CTRL MODIFIER TO OPERATE ON GRAPHS WITH MOUSE & KEYBOARD
|
||||
###########################################################################
|
||||
#### if enabled forces to hold Control key pressed to operate on graphs
|
||||
#### to prevent "graph event stealing to schematic"
|
||||
#### Default: 0 (not set)
|
||||
# set graph_use_ctrl_key 1
|
||||
|
||||
###########################################################################
|
||||
#### HIDE GRAPHS IF NO SPICE DATA LOADED
|
||||
###########################################################################
|
||||
|
|
@ -560,6 +598,16 @@ set editor {notepad.exe}
|
|||
#### default: not enabled (0)
|
||||
# set hide_empty_graphs 0
|
||||
|
||||
|
||||
###########################################################################
|
||||
#### ATTACH HOOK FUNCTION TO CURSOR 2 MOVEMENT
|
||||
###########################################################################
|
||||
#### if enabled whenever the cursor2 is moved the specified script is
|
||||
#### executed. Examples:
|
||||
#### set cursor_2_hook {conducting_devices 10e-3 nodraw}
|
||||
#### set cursor_2_hook {hilight_high_nets 0 1.8 nodraw}
|
||||
#### this can be used to add backannotation actions.
|
||||
|
||||
###########################################################################
|
||||
#### LIVE BACKANNOTATION OF DATA AT CURSOR 2 (B) POSITION
|
||||
###########################################################################
|
||||
|
|
@ -591,3 +639,6 @@ set editor {notepad.exe}
|
|||
#### Default: not enabled (0)
|
||||
# set fix_mouse_coord 0
|
||||
|
||||
#### redefine some variables to emulate Cadence UI / bindkeys
|
||||
# source /home/schippes/share/xschem/cadence_style_rc
|
||||
|
||||
|
|
|
|||
|
|
@ -551,6 +551,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li><kbd> abort_operation</kbd></li><pre>
|
||||
|
|
@ -588,7 +589,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
all inside selected instances will be deleted </pre>
|
||||
<li><kbd> build_colors</kbd></li><pre>
|
||||
Rebuild color palette using values of tcl vars dim_value and dim_bg </pre>
|
||||
<li><kbd> callback winpath event mx my key button aux state</kbd></li><pre>
|
||||
<li><kbd> callback win_path event mx my key button aux state</kbd></li><pre>
|
||||
Invoke the callback event dispatcher with a software event </pre>
|
||||
<li><kbd> case_insensitive 1|0</kbd></li><pre>
|
||||
Set case insensitive symbol lookup. Use only on case insensitive filesystems </pre>
|
||||
|
|
@ -713,6 +714,8 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> escape_chars source [charset]</kbd></li><pre>
|
||||
escape tcl special characters with backslash
|
||||
if charset is given escape characters in charset </pre>
|
||||
<li><kbd> eval_expr str</kbd></li><pre>
|
||||
debug function: evaluate arithmetic expression in str </pre>
|
||||
<li><kbd> exit [exit_code] [closewindow] [force]</kbd></li><pre>
|
||||
Exit the program, ask for confirm if current file modified.
|
||||
if exit_code is given exit with its value, otherwise use 0 exit code
|
||||
|
|
@ -757,6 +760,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> bbox </kbd> bounding box schematic </li>
|
||||
<li><kbd> bbox_hilighted </kbd> bounding box of highlinhted objects </li>
|
||||
<li><kbd> bbox_selected </kbd> bounding box of selected objects </li>
|
||||
<li><kbd> build_date </kbd> time and date this file was built. </li>
|
||||
<li><kbd> cadlayers </kbd> number of layers </li>
|
||||
<li><kbd> case_insensitive </kbd> case_insensitive symbol matching </li>
|
||||
<li><kbd> color_ps </kbd> color postscript flag </li>
|
||||
|
|
@ -974,7 +978,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
Example: xschem instances_to_net PANEL
|
||||
--> { {Vsw} {plus} {580} {-560} } { {p2} {p} {660} {-440} }
|
||||
{ {Vpanel1} {minus} {600} {-440} } </pre>
|
||||
<li><kbd> is_symgen symbol</kbd></li><pre>
|
||||
<li><kbd> is_generator symbol</kbd></li><pre>
|
||||
tell if 'symbol' is a generator (symbol(param1,param2,...) </pre>
|
||||
<li><kbd> line [x1 y1 x2 y2] [pos] [propstring] [draw]</kbd></li><pre>
|
||||
if 'x1 y1 x2 y2'is given place line on current
|
||||
|
|
@ -1025,6 +1029,11 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
If 'f' is given output stderr messages to file 'f'
|
||||
if 'f' is not given and a file log is open, close log
|
||||
file and resume logging to stderr </pre>
|
||||
<li><kbd> load_symbol [symbol_file]</kbd></li><pre>
|
||||
Load specified symbol_file
|
||||
Returns:
|
||||
>= 0: symbol is already loaded or has been loaded
|
||||
< 0: symbol was not loaded</pre>
|
||||
<li><kbd> log_write text</kbd></li><pre>
|
||||
write given string to log file, so tcl can write messages on the log file</pre>
|
||||
<li><kbd> logic_get_net net_name</kbd></li><pre>
|
||||
|
|
@ -1096,22 +1105,22 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> new_process [f]</kbd></li><pre>
|
||||
Start a new xschem process for a schematic.
|
||||
If 'f' is given load specified schematic. </pre>
|
||||
<li><kbd> new_schematic create|destroy|destroy_all|switch winpath file [draw]</kbd></li><pre>
|
||||
<li><kbd> new_schematic create|destroy|destroy_all|switch win_path file [draw]</kbd></li><pre>
|
||||
Open/destroy a new tab or window
|
||||
create: create new empty window or with 'file' loaded if 'file' given.
|
||||
The winpath must be given (even {} is ok).
|
||||
non empty winpath ({1}) will avoid warnings if opening the
|
||||
The win_path must be given (even {} is ok).
|
||||
non empty win_path ({1}) will avoid warnings if opening the
|
||||
same file multiple times.
|
||||
destroy: destroy tab/window identified by winpath. Example:
|
||||
destroy: destroy tab/window identified by win_path. Example:
|
||||
xschem new_schematic destroy .x1.drw
|
||||
destroy_all: close all tabs/additional windows
|
||||
if the 'force'argument is given do not issue a warning if modified
|
||||
tabs are about to be closed.
|
||||
switch: switch context to specified 'winpath' window or specified schematic name
|
||||
switch: switch context to specified 'win_path' window or specified schematic name
|
||||
If 'draw' is given and set to 0 do not redraw after switching tab
|
||||
(only tab i/f)
|
||||
Main window/tab has winpath set to .drw,
|
||||
Additional windows/tabs have winpath set to .x1.drw, .x2.drw and so on...</pre>
|
||||
Main window/tab has win_path set to .drw,
|
||||
Additional windows/tabs have win_path set to .x1.drw, .x2.drw and so on...</pre>
|
||||
<li><kbd> only_probes</kbd></li><pre>
|
||||
dim schematic to better show highlights </pre>
|
||||
<li><kbd> origin x y [zoom]</kbd></li><pre>
|
||||
|
|
@ -1146,7 +1155,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
Start a GUI placement of a text object </pre>
|
||||
<li><kbd> polygon</kbd></li><pre>
|
||||
Start a GUI placement of a polygon </pre>
|
||||
<li><kbd> preview_window create|draw|destroy|close [winpath] [file]</kbd></li><pre>
|
||||
<li><kbd> preview_window create|draw|destroy|close [win_path] [file]</kbd></li><pre>
|
||||
destroy: will delete preview schematic data and destroy container window
|
||||
close: same as destroy but leave the container window.
|
||||
Used in fileselector to show a schematic preview.</pre>
|
||||
|
|
@ -1548,7 +1557,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
<li><kbd> switch [window_path |schematic_name]</kbd></li><pre>
|
||||
Switch context to indicated window path or schematic name
|
||||
returns 0 if switch was successfull or 1 in case of errors
|
||||
(no tabs/windows present or no matching winpath / schematic name
|
||||
(no tabs/windows present or no matching win_path / schematic name
|
||||
found).</pre>
|
||||
<li><kbd> symbols [n | 'derived_symbols']</kbd></li><pre>
|
||||
if 'n' given list symbol with name or number 'n', else list all
|
||||
|
|
@ -1723,7 +1732,6 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ put /local/install_shares {
|
|||
symgen.awk order_labels.awk sort_labels.awk spice.awk tedax.awk verilog.awk
|
||||
vhdl.awk hspice_backannotate.tcl add_custom_menu.tcl create_graph.tcl
|
||||
add_custom_button.tcl change_index.tcl icon.xpm resources.tcl xschemrc
|
||||
ngspice_backannotate.tcl gschemtoxschem.awk mouse_bindings.tcl
|
||||
ngspice_backannotate.tcl gschemtoxschem.awk mouse_bindings.tcl cadence_style_rc
|
||||
place_sym_pins.tcl place_pins.tcl make_sch_from_spice.awk make_sym_from_spice.awk
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ expandlabel.c expandlabel.h: expandlabel.y
|
|||
bison -d -o expandlabel.c expandlabel.y
|
||||
|
||||
eval_expr.c: eval_expr.y
|
||||
bison -o eval_expr.c eval_expr.y
|
||||
bison -p kk -o eval_expr.c eval_expr.y
|
||||
|
||||
parselabel.o: expandlabel.h
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ unsigned int hash_file(const char *f, int skip_path_lines)
|
|||
int cr = 0;
|
||||
unsigned int h=5381;
|
||||
char *line = NULL;
|
||||
fd = fopen(f, "r"); /* windows won't return \r in the lines and we chop them out anyway in the code */
|
||||
fd = my_fopen(f, "r"); /* windows won't return \r in the lines and we chop them out anyway in the code */
|
||||
if(fd) {
|
||||
while((line = my_fgets(fd, &n))) {
|
||||
/* skip lines of type: '** sch_path: ...' or '-- sch_path: ...' or '// sym_path: ...'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# run with $> xschem --script /path/to/cadence_style_rc
|
||||
set draw_crosshair 1
|
||||
set crosshair_size 2
|
||||
set infix_interface 0
|
||||
set cadence_compat 1
|
||||
set orthogonal_wiring 1
|
||||
set snap_cursor 1
|
||||
set snap_cursor_size 4
|
||||
set persistent_command 1
|
||||
set use_cursor_for_selection 1
|
||||
|
|
@ -460,7 +460,7 @@ cairo_surface_t *cairo_image_surface_create_from_jpeg_stream(cairo_read_func_t r
|
|||
* @return Returns a pointer to a cairo_surface_t structure. It should be
|
||||
* checked with cairo_surface_status() for errors.
|
||||
* @note If the returned surface is invalid you can use errno to determine
|
||||
* further reasons. Errno is set according to fopen(3) and malloc(3). If you
|
||||
* further reasons. Errno is set according to my_fopen(3) and malloc(3). If you
|
||||
* intend to check errno you shall set it to 0 before calling this function
|
||||
* because it does not modify errno itself.
|
||||
*/
|
||||
|
|
@ -520,7 +520,7 @@ static cairo_status_t cj_read(void *closure, unsigned char *data, unsigned int l
|
|||
* @return Returns a pointer to a cairo_surface_t structure. It should be
|
||||
* checked with cairo_surface_status() for errors.
|
||||
* @note If the returned surface is invalid you can use errno to determine
|
||||
* further reasons. Errno is set according to fopen(3) and malloc(3). If you
|
||||
* further reasons. Errno is set according to my_fopen(3) and malloc(3). If you
|
||||
* intend to check errno you shall set it to 0 before calling this function
|
||||
* because it does not modify errno itself.
|
||||
*/
|
||||
|
|
|
|||
148
src/callback.c
148
src/callback.c
|
|
@ -151,6 +151,8 @@ void abort_operation(void)
|
|||
tcleval("set constr_mv 0" );
|
||||
dbg(1, "abort_operation(): Escape: ui_state=%d, last_command=%d\n", xctx->ui_state, xctx->last_command);
|
||||
xctx->constr_mv=0;
|
||||
|
||||
if(xctx->ui_state & STARTPOLYGON) new_polygon(END, xctx->mousex_snap, xctx->mousey_snap);
|
||||
if(xctx->last_command && xctx->ui_state & (STARTWIRE | STARTLINE)) {
|
||||
if(xctx->ui_state & STARTWIRE) new_wire(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap);
|
||||
if(xctx->ui_state & STARTLINE) new_line(RUBBER|CLEAR, xctx->mousex_snap, xctx->mousey_snap);
|
||||
|
|
@ -220,6 +222,7 @@ static void start_line(double mx, double my)
|
|||
if(xctx->constr_mv == 1) my = xctx->my_double_save;
|
||||
if(xctx->constr_mv == 2) mx = xctx->mx_double_save;
|
||||
} else {
|
||||
xctx->manhattan_lines = 0;
|
||||
xctx->mx_double_save=mx;
|
||||
xctx->my_double_save=my;
|
||||
}
|
||||
|
|
@ -228,30 +231,31 @@ static void start_line(double mx, double my)
|
|||
|
||||
static void start_wire(double mx, double my)
|
||||
{
|
||||
dbg(1, "start_wire(): ui_state=%d, ui_state2=%d last_command=%d\n", xctx->ui_state, xctx->ui_state2, xctx->last_command);
|
||||
xctx->last_command = STARTWIRE;
|
||||
if(xctx->ui_state & STARTWIRE) {
|
||||
if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){
|
||||
xctx->constr_mv = xctx->manhattan_lines;
|
||||
new_wire(CLEAR, mx, my);
|
||||
redraw_w_a_l_r_p_z_rubbers(1);
|
||||
}
|
||||
if(xctx->constr_mv != 2) {
|
||||
xctx->mx_double_save = mx;
|
||||
}
|
||||
if(xctx->constr_mv != 1) {
|
||||
xctx->my_double_save = my;
|
||||
}
|
||||
if(xctx->constr_mv == 1) my = xctx->my_double_save;
|
||||
if(xctx->constr_mv == 2) mx = xctx->mx_double_save;
|
||||
} else {
|
||||
xctx->mx_double_save=mx;
|
||||
xctx->my_double_save=my;
|
||||
}
|
||||
new_wire(PLACE,mx, my);
|
||||
if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){
|
||||
xctx->constr_mv = 0;
|
||||
}
|
||||
dbg(1, "start_wire(): ui_state=%d, ui_state2=%d last_command=%d\n",
|
||||
xctx->ui_state, xctx->ui_state2, xctx->last_command);
|
||||
xctx->last_command = STARTWIRE;
|
||||
if(xctx->ui_state & STARTWIRE) {
|
||||
if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){
|
||||
xctx->constr_mv = xctx->manhattan_lines;
|
||||
new_wire(CLEAR, mx, my);
|
||||
redraw_w_a_l_r_p_z_rubbers(1);
|
||||
}
|
||||
if(xctx->constr_mv != 2) {
|
||||
xctx->mx_double_save = mx;
|
||||
}
|
||||
if(xctx->constr_mv != 1) {
|
||||
xctx->my_double_save = my;
|
||||
}
|
||||
if(xctx->constr_mv == 1) my = xctx->my_double_save;
|
||||
if(xctx->constr_mv == 2) mx = xctx->mx_double_save;
|
||||
} else {
|
||||
xctx->mx_double_save=mx;
|
||||
xctx->my_double_save=my;
|
||||
}
|
||||
new_wire(PLACE,mx, my);
|
||||
if(tclgetboolvar("orthogonal_wiring") && !tclgetboolvar("constr_mv")){
|
||||
xctx->constr_mv = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static double interpolate_yval(int idx, int p, double x, int sweep_idx, int point_not_last)
|
||||
|
|
@ -1641,11 +1645,11 @@ static int end_place_move_copy_zoom()
|
|||
}
|
||||
xctx->constr_mv=0;
|
||||
tcleval("set constr_mv 0" );
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
else if(xctx->ui_state & STARTARC) {
|
||||
new_arc(SET, 0, xctx->mousex_snap, xctx->mousey_snap);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
else if(xctx->ui_state & STARTLINE) {
|
||||
if(tclgetboolvar("persistent_command")) {
|
||||
|
|
@ -1663,11 +1667,11 @@ static int end_place_move_copy_zoom()
|
|||
}
|
||||
xctx->constr_mv=0;
|
||||
tcleval("set constr_mv 0" );
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
else if(xctx->ui_state & STARTRECT) {
|
||||
new_rect(PLACE|END,xctx->mousex_snap, xctx->mousey_snap);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
else if(xctx->ui_state & STARTPOLYGON) {
|
||||
if(xctx->constr_mv == 1) xctx->mousey_snap = xctx->my_double_save;
|
||||
|
|
@ -1677,7 +1681,7 @@ static int end_place_move_copy_zoom()
|
|||
xctx->my_double_save=xctx->mousey_snap;
|
||||
xctx->constr_mv=0;
|
||||
tcleval("set constr_mv 0" );
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
else if(xctx->ui_state & STARTMOVE) {
|
||||
move_objects(END,0,0,0);
|
||||
|
|
@ -1721,7 +1725,7 @@ void snapped_wire(double c_snap)
|
|||
new_wire(PLACE|END, x, y);
|
||||
xctx->constr_mv=0;
|
||||
tcleval("set constr_mv 0" );
|
||||
if((xctx->ui_state & MENUSTART) && !tclgetboolvar("persistent_command") ) xctx->ui_state &= ~MENUSTART;
|
||||
if((xctx->ui_state & MENUSTART) && !tclgetboolvar("persistent_command") ) xctx->ui_state &= ~MENUSTART; /*CD*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2459,6 +2463,7 @@ static void handle_enter_notify(int draw_xhair, int crosshair_size)
|
|||
xctx->mousey_snap = -340;
|
||||
merge_file(1, ".sch");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2471,6 +2476,7 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
|
|||
}
|
||||
if(draw_xhair) {
|
||||
draw_crosshair(1, state); /* when moving mouse: first action is delete crosshair, will be drawn later */
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
|
||||
}
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(1);
|
||||
/* pan schematic */
|
||||
|
|
@ -2582,6 +2588,7 @@ static void handle_motion_notify(int event, KeySym key, int state, int rstate, i
|
|||
draw_crosshair(2, state); /* what = 2(draw) */
|
||||
}
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(2);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2777,12 +2784,12 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
|
|||
{
|
||||
int x;
|
||||
xctx->fill_pattern++;
|
||||
if(xctx->fill_pattern==3) xctx->fill_pattern=0;
|
||||
if(xctx->fill_pattern==2) xctx->fill_pattern=0;
|
||||
|
||||
if(xctx->fill_pattern==1) {
|
||||
tcleval("alert_ { Stippled pattern fill} {}");
|
||||
for(x=0;x<cadlayers;x++) {
|
||||
if(xctx->fill_type[x]==1) XSetFillStyle(display,xctx->gcstipple[x],FillSolid);
|
||||
if(xctx->fill_type[x]==2) XSetFillStyle(display,xctx->gcstipple[x],FillSolid);
|
||||
else XSetFillStyle(display,xctx->gcstipple[x],FillStippled);
|
||||
}
|
||||
}
|
||||
|
|
@ -2837,6 +2844,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
|
|||
{
|
||||
int prev_state = xctx->ui_state;
|
||||
if(xctx->semaphore >= 2) return;
|
||||
|
||||
if(infix_interface) {
|
||||
start_wire(xctx->mousex_snap, xctx->mousey_snap);
|
||||
if(prev_state == STARTWIRE) {
|
||||
|
|
@ -2881,7 +2889,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
|
|||
{
|
||||
view_zoom(0.0); return;
|
||||
}
|
||||
if(key=='z' && EQUAL_MODMASK) /* toggle snap-cursor option */
|
||||
if(key=='z' && EQUAL_MODMASK && cadence_compat) /* toggle snap-cursor option */
|
||||
{
|
||||
if(tclgetboolvar("snap_cursor")) {
|
||||
tclsetvar("snap_cursor", "0");
|
||||
|
|
@ -3435,7 +3443,6 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
|
|||
int tool = 0;
|
||||
int exists = 0;
|
||||
char *tool_name = NULL;
|
||||
char str[200];
|
||||
|
||||
if(xctx->semaphore >= 2) return;
|
||||
tcleval("winfo exists .graphdialog");
|
||||
|
|
@ -3451,7 +3458,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
|
|||
if(exists) {
|
||||
if(!tool) {
|
||||
tool = tclgetintvar("sim(spicewave,default)");
|
||||
my_snprintf(str, S(str), "sim(spicewave,%d,name)", tool);
|
||||
my_snprintf(str, PATH_MAX + 100, "sim(spicewave,%d,name)", tool);
|
||||
my_strdup(_ALLOC_ID_, &tool_name, tclgetvar(str));
|
||||
dbg(1,"callback(): tool_name=%s\n", tool_name);
|
||||
if(strstr(tool_name, "Gaw")) tool=GAW;
|
||||
|
|
@ -3475,7 +3482,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
|
|||
}
|
||||
if(key=='g' && rstate==ControlMask) /* set snap factor 20161212 */
|
||||
{
|
||||
my_snprintf(str, S(str),
|
||||
my_snprintf(str, S(str),
|
||||
"input_line {Enter snap value (default: %.16g current: %.16g)} {xschem set cadsnap} {%g} 10",
|
||||
CADSNAP, c_snap, c_snap);
|
||||
tcleval(str);
|
||||
|
|
@ -4087,6 +4094,7 @@ static void handle_key_press(int event, KeySym key, int state, int rstate, int m
|
|||
break_wires_at_pins(1);
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4094,6 +4102,8 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
|
|||
double c_snap, int draw_xhair, int crosshair_size, int enable_stretch, int aux)
|
||||
{
|
||||
dbg(1, "callback(): ButtonPress ui_state=%d state=%d\n",xctx->ui_state,state);
|
||||
int use_cursor_for_sel = tclgetintvar("use_cursor_for_selection");
|
||||
int excl = xctx->ui_state & (STARTWIRE | STARTRECT | STARTLINE | STARTPOLYGON | STARTARC);
|
||||
if(waves_selected(event, key, state, button)) {
|
||||
waves_callback(event, mx, my, key, button, aux, state);
|
||||
return;
|
||||
|
|
@ -4105,7 +4115,7 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
|
|||
}
|
||||
|
||||
/* select instance and connected nets stopping at wire junctions */
|
||||
if(button == Button3 && state == ControlMask && xctx->semaphore <2)
|
||||
if(!excl && button == Button3 && state == ControlMask && xctx->semaphore <2)
|
||||
{
|
||||
Selected sel;
|
||||
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
|
||||
|
|
@ -4113,17 +4123,19 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
|
|||
}
|
||||
|
||||
/* break wire at mouse coordinates, move break point to nearest grid point */
|
||||
else if(button == Button3 && EQUAL_MODMASK && !(state & ShiftMask) && xctx->semaphore <2)
|
||||
else if(!excl && button == Button3 && EQUAL_MODMASK &&
|
||||
!(state & ShiftMask) && xctx->semaphore <2)
|
||||
{
|
||||
break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 1);
|
||||
}
|
||||
/* break wire at mouse coordinates */
|
||||
else if(button == Button3 && EQUAL_MODMASK && (state & ShiftMask) && xctx->semaphore <2)
|
||||
else if(!excl && button == Button3 && EQUAL_MODMASK &&
|
||||
(state & ShiftMask) && xctx->semaphore <2)
|
||||
{
|
||||
break_wires_at_point(xctx->mousex_snap, xctx->mousey_snap, 0);
|
||||
}
|
||||
/* select instance and connected nets NOT stopping at wire junctions */
|
||||
else if(button == Button3 && state == ShiftMask && xctx->semaphore <2)
|
||||
else if(!excl && button == Button3 && state == ShiftMask && xctx->semaphore <2)
|
||||
{
|
||||
Selected sel;
|
||||
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 0, NULL);
|
||||
|
|
@ -4131,13 +4143,13 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
|
|||
}
|
||||
/* moved to Button3 release */
|
||||
/*
|
||||
* else if(button == Button3 && state == 0 && xctx->semaphore <2) {
|
||||
* else if(button == Button3 && state == 0 && xctx->semaphore <2) {
|
||||
* context_menu_action(xctx->mousex_snap, xctx->mousey_snap);
|
||||
* }
|
||||
*/
|
||||
|
||||
/* zoom rectangle by right clicking and drag */
|
||||
else if(button == Button3 && state == 0 && xctx->semaphore < 2) {
|
||||
else if(!excl && button == Button3 && state == 0 && xctx->semaphore < 2) {
|
||||
zoom_rectangle(START);return;
|
||||
}
|
||||
|
||||
|
|
@ -4187,18 +4199,18 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
|
|||
if(tclgetboolvar("persistent_command") && xctx->last_command) {
|
||||
if(xctx->last_command == STARTLINE) start_line(xctx->mousex_snap, xctx->mousey_snap);
|
||||
if(xctx->last_command == STARTWIRE){
|
||||
if(tclgetboolvar("snap_cursor")
|
||||
&& (xctx->prev_snapx == xctx->mousex_snap
|
||||
&& xctx->prev_snapy == xctx->mousey_snap)
|
||||
&& (xctx->ui_state & STARTWIRE)
|
||||
&& xctx->closest_pin_found){
|
||||
new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap);
|
||||
xctx->ui_state &= ~STARTWIRE;
|
||||
}
|
||||
else
|
||||
start_wire(xctx->mousex_snap, xctx->mousey_snap);
|
||||
}
|
||||
return;
|
||||
if(tclgetboolvar("snap_cursor")
|
||||
&& (xctx->prev_snapx == xctx->mousex_snap
|
||||
&& xctx->prev_snapy == xctx->mousey_snap)
|
||||
&& (xctx->ui_state & STARTWIRE)
|
||||
&& xctx->closest_pin_found){
|
||||
new_wire(PLACE|END, xctx->mousex_snap, xctx->mousey_snap);
|
||||
xctx->ui_state &= ~STARTWIRE;
|
||||
}
|
||||
else
|
||||
start_wire(xctx->mousex_snap, xctx->mousey_snap);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* handle all object insertions started from Tools/Edit menu */
|
||||
if(check_menu_start_commands(c_snap, mx, my)) return;
|
||||
|
|
@ -4207,7 +4219,7 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
|
|||
if(end_place_move_copy_zoom()) return;
|
||||
|
||||
/* Button1Press to select objects */
|
||||
if( !(xctx->ui_state & STARTSELECT) && !(xctx->ui_state & STARTWIRE) && !(xctx->ui_state & STARTLINE) ) {
|
||||
if(!excl) {
|
||||
Selected sel;
|
||||
int already_selected = 0;
|
||||
int prev_last_sel = xctx->lastsel;
|
||||
|
|
@ -4234,7 +4246,7 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
|
|||
|
||||
/* find closest object. Use snap coordinates if full crosshair is enabled
|
||||
* since the mouse pointer is obscured and crosshair is snapped to grid points */
|
||||
if(draw_xhair) {
|
||||
if(draw_xhair && (use_cursor_for_sel || crosshair_size == 0)) {
|
||||
sel = find_closest_obj(xctx->mousex_snap, xctx->mousey_snap, 0);
|
||||
} else {
|
||||
sel = find_closest_obj(xctx->mousex, xctx->mousey, 0);
|
||||
|
|
@ -4330,8 +4342,9 @@ static void handle_button_press(int event, int state, int rstate, KeySym key, in
|
|||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
} /* if(!excl) */
|
||||
} /* button==Button1 */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4373,12 +4386,12 @@ static void handle_button_release(int event, KeySym key, int state, int button,
|
|||
xctx->semaphore = savesem;
|
||||
}
|
||||
|
||||
/* end wire creation when dragging in intuitive interface from an inst pin ow wire endpoint */
|
||||
/*else if(state == Button1Mask && xctx->intuitive_interface
|
||||
* && (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) {*/
|
||||
/* if(end_place_move_copy_zoom()) break;*/
|
||||
/*}*/
|
||||
|
||||
/* end wire creation when dragging in intuitive interface from an inst pin or wire endpoint */
|
||||
else if(state == Button1Mask && xctx->intuitive_interface && !tclgetboolvar("persistent_command")
|
||||
&& (xctx->ui_state & STARTWIRE) && !(xctx->ui_state & MENUSTART)) {
|
||||
if(end_place_move_copy_zoom()) return;
|
||||
}
|
||||
|
||||
/* end intuitive_interface copy or move */
|
||||
if(xctx->ui_state & STARTCOPY && xctx->drag_elements) {
|
||||
copy_objects(END);
|
||||
|
|
@ -4432,6 +4445,7 @@ static void handle_button_release(int event, KeySym key, int state, int button,
|
|||
}
|
||||
if(draw_xhair) draw_crosshair(3, state); /* restore crosshair when selecting / unselecting */
|
||||
if(snap_cursor && wire_draw_active) draw_snap_cursor(3);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -4471,9 +4485,10 @@ static void handle_double_click(int event, int state, KeySym key, int button,
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* main window callback */
|
||||
/* mx and my are set to the mouse coord. relative to window */
|
||||
/* win_path: set to .drw or sub windows .x1.drw, .x2.drw, ... */
|
||||
|
|
@ -4493,12 +4508,12 @@ int enable_stretch = tclgetboolvar("enable_stretch");
|
|||
int draw_xhair = tclgetboolvar("draw_crosshair");
|
||||
int crosshair_size = tclgetintvar("crosshair_size");
|
||||
int infix_interface = tclgetboolvar("infix_interface");
|
||||
int rstate; /* (reduced state, without ShiftMask) */
|
||||
int snap_cursor = tclgetboolvar("snap_cursor");
|
||||
int cadence_compat = tclgetboolvar("cadence_compat");
|
||||
int wire_draw_active = (xctx->ui_state & STARTWIRE) ||
|
||||
((xctx->ui_state2 & MENUSTARTWIRE) && (xctx->ui_state & MENUSTART)) ||
|
||||
(tclgetboolvar("persistent_command") && (xctx->last_command & STARTWIRE));
|
||||
int rstate; /* (reduced state, without ShiftMask) */
|
||||
|
||||
/* this fix uses an alternative method for getting mouse coordinates on KeyPress/KeyRelease
|
||||
* events. Some remote connection softwares do not generate the correct coordinates
|
||||
|
|
@ -4537,6 +4552,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
} else {
|
||||
tclvareval(xctx->top_path, ".statusbar.10 configure -state normal -text { }", NULL);
|
||||
}
|
||||
|
||||
tclvareval(xctx->top_path, ".statusbar.7 configure -text $netlist_type", NULL);
|
||||
tclvareval(xctx->top_path, ".statusbar.3 delete 0 end;",
|
||||
xctx->top_path, ".statusbar.3 insert 0 $cadsnap",
|
||||
|
|
@ -4583,7 +4599,7 @@ int rstate; /* (reduced state, without ShiftMask) */
|
|||
state &= ~Mod2Mask; /* 20170511 filter out NumLock status */
|
||||
state &= ~LockMask; /* filter out Caps Lock */
|
||||
rstate = state; /* rstate does not have ShiftMask bit, so easier to test for KeyPress events */
|
||||
rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sifficient */
|
||||
rstate &= ~ShiftMask; /* don't use ShiftMask, identifying characters is sufficient */
|
||||
rstate &= ~Button1Mask; /* ignore button-1 */
|
||||
if(xctx->semaphore >= 2)
|
||||
{
|
||||
|
|
|
|||
52
src/draw.c
52
src/draw.c
|
|
@ -1591,9 +1591,9 @@ void drawarc(int c, int what, double x, double y, double r, double a, double b,
|
|||
(int)(xx2-xx1), (int)(yy2-yy1), (int)(a*64), (int)(b*64));
|
||||
}
|
||||
|
||||
if(xctx->fill_pattern && (xctx->fill_type[c] || arc_fill == 3) ){
|
||||
if(xctx->fill_pattern && (xctx->fill_type[c] || arc_fill == 2) ){
|
||||
|
||||
if(arc_fill & 2) gc = xctx->gc[c];
|
||||
if(arc_fill == 2) gc = xctx->gc[c];
|
||||
else gc = xctx->gcstipple[c];
|
||||
if(arc_fill) {
|
||||
if(xctx->draw_window)
|
||||
|
|
@ -1631,8 +1631,8 @@ void filledrect(int c, int what, double rectx1,double recty1,double rectx2,doubl
|
|||
|
||||
if(!has_x) return;
|
||||
if(!xctx->fill_pattern) return;
|
||||
if(fill != 3 && !xctx->fill_type[c]) return;
|
||||
if(fill == 3) { /* full fill */
|
||||
if(fill != 2 && !xctx->fill_type[c]) return;
|
||||
if(fill == 2) { /* full fill */
|
||||
gc = xctx->gc[c];
|
||||
r = rf;
|
||||
i = &iif;
|
||||
|
|
@ -1782,7 +1782,7 @@ void arc_bbox(double x, double y, double r, double a, double b,
|
|||
/* Convex Nonconvex Complex */
|
||||
#define Polygontype Nonconvex
|
||||
|
||||
/* fill = 1: stippled fill, fill == 3: solid fill */
|
||||
/* fill = 1: stippled fill, fill == 2: solid fill */
|
||||
void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int fill)
|
||||
{
|
||||
const double bez_steps = 1.0/32.0; /* divide the t = [0,1] interval into 32 steps */
|
||||
|
|
@ -1846,7 +1846,7 @@ void drawbezier(Drawable w, GC gc, int c, double *x, double *y, int points, int
|
|||
XDrawLines(display, w, gc, p, i, CoordModeOrigin);
|
||||
if(fill == 1)
|
||||
XFillPolygon(display, w, xctx->gcstipple[c], p, i, Polygontype, CoordModeOrigin);
|
||||
else if(fill==3)
|
||||
else if(fill==2)
|
||||
XFillPolygon(display, w, xctx->gc[c], p, i, Polygontype, CoordModeOrigin);
|
||||
}
|
||||
|
||||
|
|
@ -1882,7 +1882,7 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil
|
|||
for(i=0;i<points; ++i) p[i].x = (short)X_TO_SCREEN(x[i]);
|
||||
for(i=0;i<points; ++i) p[i].y = (short)Y_TO_SCREEN(y[i]);
|
||||
}
|
||||
fill = xctx->fill_pattern && ((xctx->fill_type[c] && poly_fill == 1) || poly_fill == 3 ) &&
|
||||
fill = xctx->fill_pattern && ((xctx->fill_type[c] && poly_fill == 1) || poly_fill == 2 ) &&
|
||||
(x[0] == x[points-1]) && (y[0] == y[points-1]);
|
||||
bezier = (flags & 1) && (points > 2);
|
||||
if(dash) {
|
||||
|
|
@ -1893,19 +1893,19 @@ void drawpolygon(int c, int what, double *x, double *y, int points, int poly_fil
|
|||
}
|
||||
if(xctx->draw_window) {
|
||||
if(bezier) {
|
||||
drawbezier(xctx->window, xctx->gc[c], c, x, y, points, fill | (poly_fill & 2) );
|
||||
drawbezier(xctx->window, xctx->gc[c], c, x, y, points, fill ? poly_fill : 0 );
|
||||
} else {
|
||||
XDrawLines(display, xctx->window, xctx->gc[c], p, points, CoordModeOrigin);
|
||||
}
|
||||
}
|
||||
if(xctx->draw_pixmap) {
|
||||
if(bezier) {
|
||||
drawbezier(xctx->save_pixmap, xctx->gc[c], c, x, y, points, fill | (poly_fill & 2) );
|
||||
drawbezier(xctx->save_pixmap, xctx->gc[c], c, x, y, points, fill ? poly_fill : 0);
|
||||
} else {
|
||||
XDrawLines(display, xctx->save_pixmap, xctx->gc[c], p, points, CoordModeOrigin);
|
||||
}
|
||||
}
|
||||
if(poly_fill & 2) gc = xctx->gc[c];
|
||||
if(poly_fill == 2) gc = xctx->gc[c];
|
||||
else gc = xctx->gcstipple[c];
|
||||
if(fill && !bezier) {
|
||||
if(xctx->draw_window)
|
||||
|
|
@ -2836,9 +2836,9 @@ static void draw_graph_grid(Graph_ctx *gr, void *ct)
|
|||
|
||||
/* clipping everything outside container area */
|
||||
/* background */
|
||||
filledrect(0, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 3, -1, -1);
|
||||
filledrect(0, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 2, -1, -1);
|
||||
/* graph bounding box */
|
||||
drawrect(GRIDLAYER, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 2, -1, -1);
|
||||
drawrect(GRIDLAYER, NOW, gr->rx1, gr->ry1, gr->rx2, gr->ry2, 0, -1, -1);
|
||||
|
||||
bbox(START, 0.0, 0.0, 0.0, 0.0);
|
||||
bbox(ADD, gr->rx1, gr->ry1, gr->rx2, gr->ry2);
|
||||
|
|
@ -3133,7 +3133,7 @@ static void draw_cursor(double active_cursorx, double other_cursorx, int cursor_
|
|||
else
|
||||
my_snprintf(tmpstr, S(tmpstr), "%s", dtoa_eng(active_cursorx));
|
||||
text_bbox(tmpstr, txtsize, txtsize, 2, flip, 0, 0, xx + xoffs, gr->ry2-1, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
|
||||
filledrect(0, NOW, tx1, ty1, tx2, ty2, 3, -1, -1);
|
||||
filledrect(0, NOW, tx1, ty1, tx2, ty2, 2, -1, -1);
|
||||
draw_string(cursor_color, NOW, tmpstr, 2, flip, 0, 0, xx + xoffs, gr->ry2-1, txtsize, txtsize);
|
||||
}
|
||||
}
|
||||
|
|
@ -3198,7 +3198,7 @@ static void draw_hcursor(double active_cursory, int cursor_color, Graph_ctx *gr)
|
|||
th = (ty2 - ty1) / 2.; /* half text height */
|
||||
ty1 -= th;
|
||||
ty2 -= th;
|
||||
filledrect(0, NOW, tx1, ty1, tx2, ty2, 3, -1, -1);
|
||||
filledrect(0, NOW, tx1, ty1, tx2, ty2, 2, -1, -1);
|
||||
draw_string(cursor_color, NOW, tmpstr, 0, 0, 0, 0, gr->rx1 + 5, yy - th, txtsize, txtsize);
|
||||
}
|
||||
}
|
||||
|
|
@ -3230,7 +3230,7 @@ static void draw_hcursor_difference(double c1, double c2, Graph_ctx *gr)
|
|||
my_snprintf(tmpstr, S(tmpstr), " %s ", dtoa_eng(diffh));
|
||||
text_bbox(tmpstr, txtsize, txtsize, 0, 0, 0, 1, xx, yy, &tx1, &ty1, &tx2, &ty2, &tmp, &dtmp);
|
||||
if( 2 * (ty2 - ty1) < diff ) {
|
||||
filledrect(0, NOW, tx1, ty1, tx2, ty2, 3, -1, -1);
|
||||
filledrect(0, NOW, tx1, ty1, tx2, ty2, 2, -1, -1);
|
||||
draw_string(3, NOW, tmpstr, 0, 0, 0, 1, xx, yy, txtsize, txtsize);
|
||||
if( a > b) {
|
||||
dtmp = a; a = b; b = dtmp;
|
||||
|
|
@ -3487,10 +3487,12 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr)
|
|||
} else {
|
||||
if(gr->hilight_wave == wcnt) {
|
||||
gr->hilight_wave = -1;
|
||||
my_strdup2(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
|
||||
my_strdup2(_ALLOC_ID_, &r->prop_ptr,
|
||||
subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
|
||||
} else {
|
||||
gr->hilight_wave = wcnt;
|
||||
my_strdup2(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
|
||||
my_strdup2(_ALLOC_ID_, &r->prop_ptr,
|
||||
subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3512,10 +3514,12 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr)
|
|||
} else {
|
||||
if(gr->hilight_wave == wcnt) {
|
||||
gr->hilight_wave = -1;
|
||||
my_strdup2(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
|
||||
my_strdup2(_ALLOC_ID_, &r->prop_ptr,
|
||||
subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
|
||||
} else {
|
||||
gr->hilight_wave = wcnt;
|
||||
my_strdup2(_ALLOC_ID_, &r->prop_ptr, subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
|
||||
my_strdup2(_ALLOC_ID_, &r->prop_ptr,
|
||||
subst_token(r->prop_ptr, "hilight_wave", my_itoa(gr->hilight_wave)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4472,7 +4476,7 @@ static cairo_surface_t *get_surface_from_file(const char *filename, const char *
|
|||
}
|
||||
filesize = (size_t)buf.st_size;
|
||||
if(filesize > 0) {
|
||||
fd = fopen(filename, fopen_read_mode);
|
||||
fd = my_fopen(filename, fopen_read_mode);
|
||||
if(fd) {
|
||||
size_t bytes_read;
|
||||
filedata = my_malloc(_ALLOC_ID_, filesize);
|
||||
|
|
@ -4530,7 +4534,7 @@ static cairo_surface_t *get_surface_from_file(const char *filename, const char *
|
|||
#endif
|
||||
}
|
||||
if(!surface || cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
|
||||
if(jpg != 1) dbg(0, "draw_image(): failure creating image surface from %s\n", filename);
|
||||
if(jpg != 1) dbg(0, "get_surface_from_file(): failure creating image surface from %s\n", filename);
|
||||
if(surface) cairo_surface_destroy(surface);
|
||||
my_free(_ALLOC_ID_, &closure.buffer);
|
||||
*buffer = NULL;
|
||||
|
|
@ -4732,7 +4736,7 @@ int draw_image(int dr, xRect *r, double *x1, double *y1, double *x2, double *y2,
|
|||
cairo_translate(xctx->cairo_ctx, x, y);
|
||||
cairo_rotate(xctx->cairo_ctx, rot * XSCH_PI * 0.5);
|
||||
if(flip && (rot == 0 || rot == 2)) cairo_scale(xctx->cairo_ctx, -scalex, scaley);
|
||||
else if(flip && (rot == 1 || rot == 3)) cairo_scale(xctx->cairo_ctx, scalex, -scaley);
|
||||
else if(flip && (rot == 1 || rot == 3)) cairo_scale(xctx->cairo_ctx, -scalex, scaley);
|
||||
else cairo_scale(xctx->cairo_ctx, scalex, scaley);
|
||||
cairo_set_source_surface(xctx->cairo_ctx, emb_ptr->image, 0. , 0.);
|
||||
cairo_rectangle(xctx->cairo_ctx, 0, 0, w , h );
|
||||
|
|
@ -4986,7 +4990,7 @@ void draw(void)
|
|||
draw_symbol(ADD, cc, i,c, 0, 0, 0.0, 0.0); /* ... then draw current layer */
|
||||
}
|
||||
}
|
||||
filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 3, -1, -1); /* last parameter must be 3! */
|
||||
filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 2, -1, -1); /* fill parameter must be 2! */
|
||||
drawarc(cc, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0);
|
||||
drawrect(cc, END, 0.0, 0.0, 0.0, 0.0, 0, -1, -1);
|
||||
drawline(cc, END, 0.0, 0.0, 0.0, 0.0, 0, NULL);
|
||||
|
|
@ -5013,7 +5017,7 @@ void draw(void)
|
|||
xctx->wire[i].x2,xctx->wire[i].y2, 0, NULL);
|
||||
}
|
||||
update_conn_cues(cc, 1, xctx->draw_window);
|
||||
filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 3, -1, -1); /* fill parameter must be 3! */
|
||||
filledrect(cc, END, 0.0, 0.0, 0.0, 0.0, 2, -1, -1); /* fill parameter must be 2! */
|
||||
drawline(cc, END, 0.0, 0.0, 0.0, 0.0, 0, NULL);
|
||||
}
|
||||
if(xctx->draw_single_layer ==-1 || xctx->draw_single_layer==TEXTLAYER) {
|
||||
|
|
|
|||
|
|
@ -586,6 +586,19 @@ char *dtoa_prec(double i)
|
|||
return s;
|
||||
}
|
||||
|
||||
FILE *my_fopen(const char *f, const char *m)
|
||||
{
|
||||
struct stat buf;
|
||||
FILE *fd = NULL;
|
||||
int st;
|
||||
|
||||
st = stat(f, &buf);
|
||||
if(st) return NULL; /* not existing or error */
|
||||
if(!S_ISREG(buf.st_mode)) return NULL; /* not a regular file/symlink to a regular file */
|
||||
fd = fopen(f, m);
|
||||
return fd;
|
||||
}
|
||||
|
||||
size_t my_mstrcat(int id, char **str, const char *add, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
|
@ -1020,7 +1033,7 @@ static int edit_rect_property(int x)
|
|||
}
|
||||
|
||||
attr = get_tok_value(xctx->rect[c][n].prop_ptr,"fill", 0);
|
||||
if(!strcmp(attr, "full")) xctx->rect[c][n].fill = 3;
|
||||
if(!strcmp(attr, "full")) xctx->rect[c][n].fill = 2;
|
||||
else if(!strboolcmp(attr, "false")) xctx->rect[c][n].fill = 0;
|
||||
else xctx->rect[c][n].fill = 1;
|
||||
|
||||
|
|
@ -1203,11 +1216,11 @@ static int edit_arc_property(void)
|
|||
old_fill = xctx->arc[c][i].fill;
|
||||
fill_ptr = get_tok_value(xctx->arc[c][i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr,"full") )
|
||||
xctx->arc[c][i].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
xctx->arc[c][i].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if( !strboolcmp(fill_ptr,"true") )
|
||||
xctx->arc[c][i].fill =1;
|
||||
xctx->arc[c][i].fill = 1;
|
||||
else
|
||||
xctx->arc[c][i].fill =0;
|
||||
xctx->arc[c][i].fill = 0;
|
||||
old_dash = xctx->arc[c][i].dash;
|
||||
dash = get_tok_value(xctx->arc[c][i].prop_ptr,"dash",0);
|
||||
if( strcmp(dash, "") ) {
|
||||
|
|
@ -1281,11 +1294,11 @@ static int edit_polygon_property(void)
|
|||
|
||||
fill_ptr = get_tok_value(xctx->poly[c][i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr,"full") )
|
||||
xctx->poly[c][i].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
xctx->poly[c][i].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if( !strboolcmp(fill_ptr,"true") )
|
||||
xctx->poly[c][i].fill =1;
|
||||
xctx->poly[c][i].fill = 1;
|
||||
else
|
||||
xctx->poly[c][i].fill =0;
|
||||
xctx->poly[c][i].fill = 0;
|
||||
dash = get_tok_value(xctx->poly[c][i].prop_ptr,"dash",0);
|
||||
if( strcmp(dash, "") ) {
|
||||
int d = atoi(dash);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h> /* For math functions, cos(), sin(), etc. */
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "xschem.h"
|
||||
|
|
@ -16,7 +15,8 @@ static int dbglev = 1;
|
|||
struct symrec
|
||||
{
|
||||
char *name; /* name of symbol */
|
||||
double (*fnctptr)(); /* value of a FNCT */
|
||||
double (*fnctptr)(double); /* value of a FNCT */
|
||||
double value;
|
||||
struct symrec *next; /* link field */
|
||||
};
|
||||
|
||||
|
|
@ -32,30 +32,42 @@ static void kkerror(char *s);
|
|||
static double toint(double x);
|
||||
static void get_expr(double x);
|
||||
static void get_char(int c);
|
||||
static double rnd6(double x) {return round_to_n_digits(x, 6);}
|
||||
|
||||
struct fn
|
||||
{
|
||||
char *fname;
|
||||
double (*fnct)();
|
||||
double value;
|
||||
};
|
||||
static int lex_state = 0;
|
||||
struct fn fn_array[]
|
||||
= {
|
||||
{"int" , toint},
|
||||
{"sin" , sin},
|
||||
{"cos" , cos},
|
||||
{"asin", asin},
|
||||
{"acos", acos},
|
||||
{"atan", atan},
|
||||
{"log" , log10},
|
||||
{"ln" , log},
|
||||
{"exp" , exp},
|
||||
{"sqrt", sqrt},
|
||||
{0 , 0}
|
||||
{"int" , toint, 0},
|
||||
{"sin" , sin, 0},
|
||||
{"cos" , cos, 0},
|
||||
{"exp" , exp, 0},
|
||||
{"asin" , asin, 0},
|
||||
{"acos" , acos, 0},
|
||||
{"atan" , atan, 0},
|
||||
{"log" , log10, 0},
|
||||
{"ln" , log, 0},
|
||||
{"exp" , exp, 0},
|
||||
{"sqrt" , sqrt, 0},
|
||||
{"round" , rnd6, 0},
|
||||
{"pi" , NULL, 3.141592653589793},
|
||||
{"e" , NULL, 2.718281828459045},
|
||||
{"k" , NULL, 1.380649e-23},
|
||||
{"h" , NULL, 6.62607e-34},
|
||||
{"echarge" , NULL, 1.60217646e-19},
|
||||
{"abszero" , NULL, 273.15},
|
||||
{"c" , NULL, 2.99792458e8},
|
||||
{0 , 0, 0}
|
||||
};
|
||||
%}
|
||||
|
||||
%define api.prefix {kk}
|
||||
|
||||
/* %define api.prefix {kk} */
|
||||
%union {
|
||||
int c;
|
||||
double val; /* For returning numbers. */
|
||||
|
|
@ -63,7 +75,7 @@ symrec *tptr; /* For returning symbol-table pointers */
|
|||
}
|
||||
|
||||
%token STREND 0
|
||||
%token <c> CHAR
|
||||
%token <c> XCHAR
|
||||
%token EXPR /* expr( */
|
||||
%token <val> NUM /* Simple double precision number */
|
||||
%token <tptr> FNCT /* Variable and Function */
|
||||
|
|
@ -81,14 +93,15 @@ input:
|
|||
;
|
||||
|
||||
line:
|
||||
CHAR {get_char($1);}
|
||||
XCHAR {get_char($1);}
|
||||
| EXPR exp ')' {get_expr($2);lex_state = 0;}
|
||||
| EXPR '\'' exp '\'' ')' {get_expr($3);lex_state = 0;}
|
||||
| EXPR exp error
|
||||
;
|
||||
|
||||
exp: NUM {$$ = $1;}
|
||||
| FNCT '(' exp ')' {$$ = $1 ? (*($1->fnctptr))($3) : 0.0;}
|
||||
| FNCT '(' exp ')' {$$ = $1 ? ($1->fnctptr ? (*($1->fnctptr))($3) : 0.0) : 0.0;}
|
||||
| FNCT {$$ = $1 ? $1->value : 0.0;}
|
||||
| exp '+' exp {$$ = $1 + $3; }
|
||||
| exp '-' exp {$$ = $1 - $3;}
|
||||
| exp '*' exp {$$ = $1 * $3;}
|
||||
|
|
@ -188,18 +201,21 @@ void eval_expr_init_table(void) /* puts arithmetic functions in table. */
|
|||
{
|
||||
ptr = putsym (fn_array[i].fname);
|
||||
ptr->fnctptr = fn_array[i].fnct;
|
||||
ptr->value = fn_array[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
void eval_expr_clear_table(void)
|
||||
{
|
||||
symrec *ptr;
|
||||
for (ptr = sym_table; ptr; ptr = ptr->next) {
|
||||
symrec *ptr = sym_table;
|
||||
while(ptr) {
|
||||
symrec *tmp = ptr;
|
||||
ptr = ptr->next;
|
||||
my_free(_ALLOC_ID_, &(tmp->name));
|
||||
my_free(_ALLOC_ID_, &tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int kklex()
|
||||
{
|
||||
|
|
@ -216,8 +232,8 @@ static int kklex()
|
|||
c = *str++;
|
||||
if(c) {
|
||||
kklval.c = c;
|
||||
dbg(dbglev, "lex(): CHAR; %c\n", c);
|
||||
return CHAR;
|
||||
dbg(dbglev, "lex(): XCHAR; %c\n", c);
|
||||
return XCHAR;
|
||||
} else {
|
||||
dbg(dbglev, "lex(): STREND\n");
|
||||
return STREND;
|
||||
|
|
@ -237,7 +253,7 @@ static int kklex()
|
|||
str--;
|
||||
|
||||
sscanf(str, "%99[.0-9a-zA-Z_]%n", s, &rd);
|
||||
kklval.val = atof_spice(s);
|
||||
kklval.val = atof_eng(s);
|
||||
str += rd;
|
||||
dbg(dbglev, "lex(): NUM: %s\n", s);
|
||||
return NUM;
|
||||
|
|
|
|||
|
|
@ -696,7 +696,7 @@ static int bus_search(const char*s)
|
|||
}
|
||||
|
||||
#ifndef __unix__
|
||||
static int win_regexec(const char *options, const char *pattern, const char *name)
|
||||
int win_regexec(const char *options, const char *pattern, const char *name)
|
||||
{
|
||||
if (options!=NULL)
|
||||
tclvareval("regexp {", options,"} {", pattern, "} {", name, "}", NULL);
|
||||
|
|
@ -754,7 +754,7 @@ int search(const char *tok, const char *val, int sub, int sel, int match_case)
|
|||
if(regcomp(&re, val , cflags)) return TCL_ERROR;
|
||||
#else
|
||||
if(!match_case) {
|
||||
regexp_options = "-nocase";
|
||||
my_strdup(_ALLOC_ID_, ®exp_options, "-nocase");
|
||||
}
|
||||
#endif
|
||||
dbg(1, "search():val=%s\n", val);
|
||||
|
|
@ -1014,6 +1014,8 @@ int search(const char *tok, const char *val, int sub, int sel, int match_case)
|
|||
}
|
||||
#ifdef __unix__
|
||||
regfree(&re);
|
||||
#else
|
||||
my_free(_ALLOC_ID_, ®exp_options);
|
||||
#endif
|
||||
xctx->draw_window = save_draw;
|
||||
my_free(_ALLOC_ID_, &tmpname);
|
||||
|
|
@ -2224,7 +2226,7 @@ void draw_hilight_net(int on_window)
|
|||
((c==TEXTWIRELAYER || c==TEXTLAYER) && symptr->texts)) {
|
||||
draw_symbol(ADD, col, i,c,0,0,0.0,0.0);
|
||||
}
|
||||
filledrect(col, END, 0.0, 0.0, 0.0, 0.0, 3, -1, -1); /* last parameter must be 3! */
|
||||
filledrect(col, END, 0.0, 0.0, 0.0, 0.0, 2, -1, -1); /* last parameter must be 2! */
|
||||
drawarc(col, END, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0);
|
||||
drawrect(col, END, 0.0, 0.0, 0.0, 0.0, 0, -1, -1);
|
||||
drawline(col, END, 0.0, 0.0, 0.0, 0.0, 0, NULL);
|
||||
|
|
|
|||
|
|
@ -1665,8 +1665,7 @@ int sym_vs_sch_pins(int all)
|
|||
/* pass through symbols, duplicated pins: do not check with schematic */
|
||||
if(rects > unique_pins) continue;
|
||||
get_sch_from_sym(filename, xctx->sym + i, -1, 0);
|
||||
if(!stat(filename, &buf)) {
|
||||
fd = fopen(filename, "r");
|
||||
if(!stat(filename, &buf) && (fd = my_fopen(filename, fopen_read_mode))) {
|
||||
pin_cnt = 0;
|
||||
endfile = 0;
|
||||
f_version[0] = '\0';
|
||||
|
|
|
|||
|
|
@ -111,10 +111,11 @@ static void check_opt(char *opt, char *optval, int type)
|
|||
} else if( (type == SHORT && *opt == 'l') || (type == LONG && !strcmp("log", opt)) ) {
|
||||
if(optval) {
|
||||
errfp = fopen(optval, "w");
|
||||
setvbuf(errfp, NULL, _IOLBF, 0); /* line (_IOLBF) or disable (_IONBF) buffering on error log */
|
||||
if(!errfp) {
|
||||
errfp = stderr;
|
||||
dbg(0, "Problems opening log file: %s\n", optval);
|
||||
} else {
|
||||
setvbuf(errfp, NULL, _IOLBF, 0); /* line (_IOLBF) or disable (_IONBF) buffering on error log */
|
||||
}
|
||||
}
|
||||
} else if( (type == SHORT && *opt == 'o') || (type == LONG && !strcmp("netlist_path", opt)) ) {
|
||||
|
|
|
|||
20
src/paste.c
20
src/paste.c
|
|
@ -120,11 +120,11 @@ static void merge_box(FILE *fd)
|
|||
|
||||
fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
ptr[i].fill =3;
|
||||
ptr[i].fill = 2;
|
||||
else if( !strboolcmp(fill_ptr, "false") )
|
||||
ptr[i].fill =0;
|
||||
ptr[i].fill = 0;
|
||||
else
|
||||
ptr[i].fill =1;
|
||||
ptr[i].fill = 1;
|
||||
set_rect_flags(&xctx->rect[c][i]); /* set cached .flags bitmask from on attributes */
|
||||
select_box(c,i, SELECTED, 1, 1);
|
||||
xctx->rects[c]++;
|
||||
|
|
@ -159,11 +159,11 @@ static void merge_arc(FILE *fd)
|
|||
|
||||
fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
ptr[i].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
ptr[i].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if( !strboolcmp(fill_ptr, "true") )
|
||||
ptr[i].fill =1;
|
||||
ptr[i].fill = 1;
|
||||
else
|
||||
ptr[i].fill =0;
|
||||
ptr[i].fill = 0;
|
||||
dash = get_tok_value(ptr[i].prop_ptr,"dash",0);
|
||||
if(strcmp(dash, "")) {
|
||||
int d = atoi(dash);
|
||||
|
|
@ -219,11 +219,11 @@ static void merge_polygon(FILE *fd)
|
|||
load_ascii_string( &ptr[i].prop_ptr, fd);
|
||||
fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
ptr[i].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
ptr[i].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if( !strboolcmp(fill_ptr, "true") )
|
||||
ptr[i].fill =1;
|
||||
ptr[i].fill = 1;
|
||||
else
|
||||
ptr[i].fill =0;
|
||||
ptr[i].fill = 0;
|
||||
dash = get_tok_value(ptr[i].prop_ptr,"dash",0);
|
||||
if(strcmp(dash, "")) {
|
||||
int d = atoi(dash);
|
||||
|
|
@ -379,7 +379,7 @@ void merge_file(int selection_load, const char ext[])
|
|||
my_free(_ALLOC_ID_, &cmd);
|
||||
} else fd = NULL;
|
||||
} else {
|
||||
fd=fopen(name, fopen_read_mode);
|
||||
fd=my_fopen(name, fopen_read_mode);
|
||||
}
|
||||
if(fd) {
|
||||
xctx->prep_hi_structs=0;
|
||||
|
|
|
|||
222
src/psprint.c
222
src/psprint.c
|
|
@ -301,7 +301,6 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
|
|||
rwi = (int)(rw * scale + 1.0);
|
||||
rhi = (int)(rh * scale + 1.0);
|
||||
dbg(1, "graph size: %dx%d\n", rwi, rhi);
|
||||
dbg(1, "ps_embedded_graph: saving zoom\n");
|
||||
save_restore_zoom(1, &zi);
|
||||
set_viewport_size(rwi, rhi, xctx->lw);
|
||||
|
||||
|
|
@ -354,7 +353,6 @@ static int ps_embedded_graph(xRect* r, double rx1, double ry1, double rx2, doubl
|
|||
cairo_surface_destroy(png_sfc);
|
||||
xctx->draw_pixmap = 1;
|
||||
tclsetboolvar("draw_grid", save_draw_grid);
|
||||
dbg(1, "ps_embedded_graph: restoring zoom\n");
|
||||
save_restore_zoom(0, &zi);
|
||||
resetwin(1, 1, 1, 0, 0);
|
||||
change_linewidth(xctx->lw);
|
||||
|
|
@ -445,11 +443,27 @@ static void ps_xdrawpoint(int layer, double x1, double y1)
|
|||
fprintf(fd, "%g %g %g %g L\n", x1, y1,x1,y1);
|
||||
}
|
||||
|
||||
static void ps_xfillrectange(int layer, double x1, double y1, double x2,
|
||||
/* fill_pattern:
|
||||
* 0 : no fill
|
||||
* 1 : stippled fill
|
||||
* 2 : solid fill
|
||||
*
|
||||
* fill_type[i]:
|
||||
* 0 : no fill
|
||||
* 1 : patterned (stippled) fill
|
||||
* 2 : solid fill
|
||||
*
|
||||
* fill:
|
||||
* 0 : no fill
|
||||
* 1 : stippled fill
|
||||
* 2 : solid fill
|
||||
*/
|
||||
|
||||
static void ps_xfillrectangle(int layer, double x1, double y1, double x2,
|
||||
double y2, int fill)
|
||||
{
|
||||
fprintf(fd, "%g %g %g %g R\n", x1,y1,x2-x1,y2-y1);
|
||||
if(fill && (xctx->fill_type[layer] == 1) && xctx->fill_pattern) {
|
||||
if(xctx->fill_pattern && xctx->fill_type[layer] && fill) {
|
||||
fprintf(fd, "%g %g %g %g RF\n", x1,y1,x2-x1,y2-y1);
|
||||
/* fprintf(fd,"fill\n"); */
|
||||
}
|
||||
|
|
@ -547,7 +561,8 @@ static void ps_drawpolygon(int c, int what, double *x, double *y, int points, in
|
|||
}
|
||||
|
||||
|
||||
static void ps_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2, int dash, int fill)
|
||||
static void ps_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2,
|
||||
int dash, int fill, int e_a, int e_b)
|
||||
{
|
||||
double x1,y1,x2,y2, tmp;
|
||||
double psdash;
|
||||
|
|
@ -562,7 +577,21 @@ static void ps_filledrect(int gc, double rectx1,double recty1,double rectx2,doub
|
|||
if(dash) {
|
||||
fprintf(fd, "[%g %g] 0 setdash\n", psdash, psdash);
|
||||
}
|
||||
ps_xfillrectange(gc, x1,y1,x2,y2, fill);
|
||||
if(e_a != -1) {
|
||||
double rx = (x2 - x1) / 2.0;
|
||||
double ry = (y2 - y1) / 2.0;
|
||||
double cx = (x2 + x1) / 2.0;
|
||||
double cy = (y2 + y1) / 2.0;
|
||||
|
||||
if(xctx->fill_pattern && xctx->fill_type[gc] && fill) {
|
||||
fprintf(fd, "%g %g MT %g %g %g %g %d %d E %g %g LT C F S\n",
|
||||
cx, cy, cx, cy, rx, ry, -e_a, -e_a-e_b, cx, cy);
|
||||
} else {
|
||||
fprintf(fd, "%g %g %g %g %d %d E S\n", cx, cy, rx, ry, -e_a, -e_a-e_b);
|
||||
}
|
||||
} else {
|
||||
ps_xfillrectangle(gc, x1,y1,x2,y2, fill);
|
||||
}
|
||||
if(dash) {
|
||||
fprintf(fd, "[] 0 setdash\n");
|
||||
}
|
||||
|
|
@ -937,7 +966,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
|
|||
#endif
|
||||
else if((xctx->inst[n].x2 - xctx->inst[n].x1) * xctx->mooz < 3 &&
|
||||
(xctx->inst[n].y2 - xctx->inst[n].y1) * xctx->mooz < 3) {
|
||||
ps_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0);
|
||||
ps_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0, -1, -1);
|
||||
xctx->inst[n].flags|=1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -946,7 +975,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
|
|||
}
|
||||
if(hide) {
|
||||
int color = (disabled==1) ? GRIDLAYER : (disabled == 2) ? PINLAYER : SYMLAYER;
|
||||
ps_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0);
|
||||
ps_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0, -1, -1);
|
||||
}
|
||||
/* pdfmarks, only if doing hierarchy print and if symbol has a subcircuit */
|
||||
if(what != 7) {
|
||||
|
|
@ -1033,6 +1062,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
|
|||
|
||||
if( (!hide && xctx->enable_layer[layer]) ||
|
||||
(hide && layer == PINLAYER && xctx->enable_layer[layer]) ) {
|
||||
if(symptr->rects[layer]) fprintf(fd, "NP\n"); /* newpath */
|
||||
for(j=0;j< symptr->rects[layer]; ++j)
|
||||
{
|
||||
int dash;
|
||||
|
|
@ -1044,9 +1074,27 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
|
|||
if (layer == GRIDLAYER && rect->flags & 1024) /* image */
|
||||
{
|
||||
ps_embedded_image(rect, x0 + x1, y0 + y1, x0 + x2, y0 + y2, rot, flip);
|
||||
continue;
|
||||
} else {
|
||||
int ellipse_a = rect->ellipse_a;
|
||||
int ellipse_b = rect->ellipse_b;
|
||||
|
||||
if(ellipse_a != -1 && ellipse_b != 360) {
|
||||
if(flip) {
|
||||
ellipse_a = 180 - ellipse_a - ellipse_b;
|
||||
}
|
||||
if(rot) {
|
||||
if(rot == 3) {
|
||||
ellipse_a += 90;
|
||||
} else if(rot == 2) {
|
||||
ellipse_a += 180;
|
||||
} else if(rot == 1) {
|
||||
ellipse_a += 270;
|
||||
}
|
||||
ellipse_a %= 360;
|
||||
}
|
||||
}
|
||||
ps_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill, ellipse_a, ellipse_b);
|
||||
}
|
||||
ps_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill);
|
||||
}
|
||||
} /* if( (!hide && xctx->enable_layer[layer]) || ... */
|
||||
|
||||
|
|
@ -1192,83 +1240,78 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
|
|||
old_grid=tclgetboolvar("draw_grid");
|
||||
tclsetvar("draw_grid", "0");
|
||||
|
||||
/* xschem window aspect ratio decides if portrait or landscape */
|
||||
boundbox.x1 = xctx->areax1;
|
||||
boundbox.x2 = xctx->areax2;
|
||||
boundbox.y1 = xctx->areay1;
|
||||
boundbox.y2 = xctx->areay2;
|
||||
dx=boundbox.x2-boundbox.x1;
|
||||
dy=boundbox.y2-boundbox.y1;
|
||||
|
||||
/* xschem drawing bbox decides if portrait or landscape */
|
||||
if(fullzoom == 1) {
|
||||
calc_drawing_bbox(&boundbox, 0);
|
||||
dx=boundbox.x2-boundbox.x1;
|
||||
dy=boundbox.y2-boundbox.y1;
|
||||
}
|
||||
if(dx >= dy) {
|
||||
landscape = 1;
|
||||
} else {
|
||||
landscape = 0;
|
||||
}
|
||||
dbg(1, "dx=%g, dy=%g\n", dx, dy);
|
||||
|
||||
|
||||
if(!(what & 4)) {
|
||||
/* xschem window aspect ratio decides if portrait or landscape */
|
||||
if(fullzoom == 1) {
|
||||
/* save size and zoom factor */
|
||||
save_restore_zoom(1, &zi);
|
||||
/* this zoom only done to reset lw */
|
||||
zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
|
||||
/* adjust aspect ratio to paper size */
|
||||
if(landscape)
|
||||
xctx->xrect[0].height = (short unsigned int) (xctx->xrect[0].width * pagey / pagex);
|
||||
else
|
||||
xctx->xrect[0].width = (short unsigned int) (xctx->xrect[0].height * pagey / pagex);
|
||||
dbg(1, "xrect.width=%d, xrect.height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
|
||||
xctx->areax1 = -2*INT_WIDTH(xctx->lw);
|
||||
xctx->areay1 = -2*INT_WIDTH(xctx->lw);
|
||||
xctx->areax2 = xctx->xrect[0].width+2*INT_WIDTH(xctx->lw);
|
||||
xctx->areay2 = xctx->xrect[0].height+2*INT_WIDTH(xctx->lw);
|
||||
xctx->areaw = xctx->areax2-xctx->areax1;
|
||||
xctx->areah = xctx->areay2 - xctx->areay1;
|
||||
dbg(1, "dx=%g, dy=%g\n", dx, dy);
|
||||
/* fit schematic into adjusted size */
|
||||
zoom_full(0, 0, 0 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
|
||||
boundbox.x1 = xctx->areax1;
|
||||
boundbox.x2 = xctx->areax2;
|
||||
boundbox.y1 = xctx->areay1;
|
||||
boundbox.y2 = xctx->areay2;
|
||||
dx=boundbox.x2-boundbox.x1;
|
||||
dy=boundbox.y2-boundbox.y1;
|
||||
|
||||
/* xschem drawing bbox decides if portrait or landscape */
|
||||
if(fullzoom == 1) {
|
||||
calc_drawing_bbox(&boundbox, 0);
|
||||
dx=boundbox.x2-boundbox.x1;
|
||||
dy=boundbox.y2-boundbox.y1;
|
||||
}
|
||||
if(dx >= dy) {
|
||||
landscape = 1;
|
||||
}
|
||||
|
||||
if(!landscape) { /* decide paper orientation for best schematic fit */
|
||||
double tmp;
|
||||
tmp = pagex;
|
||||
pagex = pagey;
|
||||
pagey = tmp;
|
||||
}
|
||||
if(fullzoom == 2) { /* set media size to bbox */
|
||||
double sc;
|
||||
my_strncpy(papername, "bbox", S(papername));
|
||||
pagex = xctx->xrect[0].width;
|
||||
pagey = xctx->xrect[0].height;
|
||||
if(pagex > pagey) {
|
||||
sc = 842. / pagex;
|
||||
pagex = my_round(pagex * sc);
|
||||
pagey = my_round(pagey * sc);
|
||||
} else {
|
||||
landscape = 0;
|
||||
sc = 842. / pagey;
|
||||
pagex = my_round(pagex * sc);
|
||||
pagey = my_round(pagey * sc);
|
||||
}
|
||||
dbg(1, "dx=%g, dy=%g\n", dx, dy);
|
||||
|
||||
|
||||
if(fullzoom == 1) {
|
||||
/* save size and zoom factor */
|
||||
dbg(1, "create_ps: saving zoom\n");
|
||||
save_restore_zoom(1, &zi);
|
||||
/* this zoom only done to reset lw */
|
||||
zoom_full(0, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
|
||||
/* adjust aspect ratio to paper size */
|
||||
if(landscape)
|
||||
xctx->xrect[0].height = (short unsigned int) (xctx->xrect[0].width * pagey / pagex);
|
||||
else
|
||||
xctx->xrect[0].width = (short unsigned int) (xctx->xrect[0].height * pagey / pagex);
|
||||
dbg(1, "xrect.width=%d, xrect.height=%d\n", xctx->xrect[0].width, xctx->xrect[0].height);
|
||||
xctx->areax1 = -2*INT_WIDTH(xctx->lw);
|
||||
xctx->areay1 = -2*INT_WIDTH(xctx->lw);
|
||||
xctx->areax2 = xctx->xrect[0].width+2*INT_WIDTH(xctx->lw);
|
||||
xctx->areay2 = xctx->xrect[0].height+2*INT_WIDTH(xctx->lw);
|
||||
xctx->areaw = xctx->areax2-xctx->areax1;
|
||||
xctx->areah = xctx->areay2 - xctx->areay1;
|
||||
dbg(1, "dx=%g, dy=%g\n", dx, dy);
|
||||
/* fit schematic into adjusted size */
|
||||
zoom_full(0, 0, 0 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
|
||||
boundbox.x1 = xctx->areax1;
|
||||
boundbox.x2 = xctx->areax2;
|
||||
boundbox.y1 = xctx->areay1;
|
||||
boundbox.y2 = xctx->areay2;
|
||||
dx=boundbox.x2-boundbox.x1;
|
||||
dy=boundbox.y2-boundbox.y1;
|
||||
}
|
||||
|
||||
if(!landscape) { /* decide paper orientation for best schematic fit */
|
||||
double tmp;
|
||||
tmp = pagex;
|
||||
pagex = pagey;
|
||||
pagey = tmp;
|
||||
}
|
||||
if(fullzoom == 2) { /* set media size to bbox */
|
||||
double sc;
|
||||
my_strncpy(papername, "bbox", S(papername));
|
||||
pagex = xctx->xrect[0].width;
|
||||
pagey = xctx->xrect[0].height;
|
||||
if(pagex > pagey) {
|
||||
sc = 842. / pagex;
|
||||
pagex = my_round(pagex * sc);
|
||||
pagey = my_round(pagey * sc);
|
||||
} else {
|
||||
sc = 842. / pagey;
|
||||
pagex = my_round(pagex * sc);
|
||||
pagey = my_round(pagey * sc);
|
||||
}
|
||||
margin = 0.0;
|
||||
}
|
||||
} /* if(!(what & 4)) */
|
||||
margin = 0.0;
|
||||
}
|
||||
|
||||
if(what & 1) {/* prolog */
|
||||
dbg(1, "ps_draw(): bbox: x1=%g y1=%g x2=%g y2=%g\n", boundbox.x1, boundbox.y1, boundbox.x2, boundbox.y2);
|
||||
|
|
@ -1338,9 +1381,23 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
|
|||
fprintf(fd,"/C {closepath} bind def\n");
|
||||
fprintf(fd,"/F {fill} bind def\n");
|
||||
fprintf(fd,"/RF {rectfill} bind def\n");
|
||||
fprintf(fd,"/E {\n"); /* function for drawing ellipses */
|
||||
fprintf(fd,"/endangle exch def\n");
|
||||
fprintf(fd,"/startangle exch def\n");
|
||||
fprintf(fd,"/yrad exch def\n");
|
||||
fprintf(fd,"/xrad exch def\n");
|
||||
fprintf(fd,"/y exch def\n");
|
||||
fprintf(fd,"/x exch def\n");
|
||||
fprintf(fd,"/savematrix matrix currentmatrix def\n");
|
||||
fprintf(fd,"x y translate\n");
|
||||
fprintf(fd,"xrad yrad scale\n");
|
||||
fprintf(fd,"0 0 1 startangle endangle arcn\n");
|
||||
fprintf(fd,"savematrix setmatrix\n");
|
||||
fprintf(fd,"} def %% ellipse\n");
|
||||
fprintf(fd, "%%%%EndProlog\n");
|
||||
}
|
||||
|
||||
|
||||
if(what & 2) { /* page */
|
||||
++numpages;
|
||||
|
||||
|
|
@ -1381,6 +1438,7 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
|
|||
for(i=0;i<xctx->lines[c]; ++i)
|
||||
ps_drawline(c, xctx->line[c][i].x1, xctx->line[c][i].y1,
|
||||
xctx->line[c][i].x2, xctx->line[c][i].y2, xctx->line[c][i].dash);
|
||||
if(xctx->rects[c]) fprintf(fd, "NP\n"); /* newpath */
|
||||
for(i=0;i<xctx->rects[c]; ++i)
|
||||
{
|
||||
|
||||
|
|
@ -1396,7 +1454,9 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
|
|||
}
|
||||
if(c != GRIDLAYER || !(xctx->rect[c][i].flags & 1) ) {
|
||||
ps_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
|
||||
xctx->rect[c][i].x2, xctx->rect[c][i].y2, xctx->rect[c][i].dash, xctx->rect[c][i].fill);
|
||||
xctx->rect[c][i].x2, xctx->rect[c][i].y2,
|
||||
xctx->rect[c][i].dash, xctx->rect[c][i].fill,
|
||||
xctx->rect[c][i].ellipse_a, xctx->rect[c][i].ellipse_b);
|
||||
}
|
||||
}
|
||||
if(xctx->arcs[c]) fprintf(fd, "NP\n"); /* newpath */
|
||||
|
|
@ -1497,7 +1557,7 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
|
|||
|
||||
dbg(1, "ps_draw(): INT_WIDTH(lw)=%d plotfile=%s\n",INT_WIDTH(xctx->lw), xctx->plotfile);
|
||||
fprintf(fd, "showpage\n\n");
|
||||
} /* if(what & 2) */
|
||||
}
|
||||
if(what & 4) { /* trailer */
|
||||
fprintf(fd, "%%%%trailer\n");
|
||||
fprintf(fd, "%%%%Pages: %d\n", numpages);
|
||||
|
|
@ -1515,10 +1575,10 @@ void create_ps(char **psfile, int what, int fullzoom, int eps)
|
|||
|
||||
|
||||
/* restore original size and zoom factor */
|
||||
if(!(what & 4) && fullzoom == 1) {
|
||||
dbg(1, "create_ps: restoring zoom\n");
|
||||
if(fullzoom == 1) {
|
||||
save_restore_zoom(0, &zi);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int ps_draw(int what, int fullzoom, int eps)
|
||||
|
|
|
|||
82
src/save.c
82
src/save.c
|
|
@ -909,7 +909,7 @@ char *base64_from_file(const char *f, size_t *length)
|
|||
stat_res = stat(f, &st);
|
||||
if (stat_res == 0 && ( (st.st_mode & S_IFMT) == S_IFREG) ) {
|
||||
len = st.st_size;
|
||||
fd = fopen(f, fopen_read_mode);
|
||||
fd = my_fopen(f, fopen_read_mode);
|
||||
if(fd) {
|
||||
size_t bytes_read;
|
||||
s = my_malloc(_ALLOC_ID_, len);
|
||||
|
|
@ -1023,7 +1023,7 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
|
|||
raw->annot_sweep_idx = -1;
|
||||
|
||||
int_hash_init(&raw->table, HASHSIZE);
|
||||
fd = fopen(f, fopen_read_mode);
|
||||
fd = my_fopen(f, fopen_read_mode);
|
||||
if(fd) {
|
||||
if((res = read_dataset(fd, rawptr, type, no_warning)) == 1) {
|
||||
int i;
|
||||
|
|
@ -1038,6 +1038,18 @@ int raw_read(const char *f, Raw **rawptr, const char *type, int no_warning, doub
|
|||
dbg(0, "Raw file data read: %s\n", f);
|
||||
dbg(0, "points=%d, vars=%d, datasets=%d sim_type=%s\n",
|
||||
raw->allpoints, raw->nvars, raw->datasets, raw->sim_type ? raw->sim_type : "<NULL>");
|
||||
|
||||
if(xctx->graph_flags & 4) { /* if cursor2 is enabled in first graph setup schematic annotation */
|
||||
if(xctx->rects[GRIDLAYER] > 0) {
|
||||
xRect *r;
|
||||
r = &xctx->rect[GRIDLAYER][0];
|
||||
if(r->flags & 1) {
|
||||
setup_graph_data(0, 0, &xctx->graph_struct);
|
||||
backannotate_at_cursor_b_pos(r, &xctx->graph_struct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/* free_rawfile(rawptr, 0, 0); */ /* do not free: already done in read_dataset()->extra_rawfile() */
|
||||
if(!no_warning) {
|
||||
|
|
@ -1455,7 +1467,7 @@ int table_read(const char *f)
|
|||
close(ufd);
|
||||
|
||||
int_hash_init(&raw->table, HASHSIZE);
|
||||
fd = fopen(f, fopen_read_mode);
|
||||
fd = my_fopen(f, fopen_read_mode);
|
||||
if(fd) {
|
||||
int nline = 0;
|
||||
int field;
|
||||
|
|
@ -2840,11 +2852,11 @@ static void load_polygon(FILE *fd)
|
|||
load_ascii_string( &ptr[i].prop_ptr, fd);
|
||||
fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
ptr[i].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
ptr[i].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if( !strboolcmp(fill_ptr, "true") )
|
||||
ptr[i].fill =1;
|
||||
ptr[i].fill = 1;
|
||||
else
|
||||
ptr[i].fill =0;
|
||||
ptr[i].fill = 0;
|
||||
dash = get_tok_value(ptr[i].prop_ptr,"dash",0);
|
||||
if(strcmp(dash, "")) {
|
||||
int d = atoi(dash);
|
||||
|
|
@ -2883,11 +2895,11 @@ static void load_arc(FILE *fd)
|
|||
|
||||
fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
ptr[i].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
ptr[i].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if( !strboolcmp(fill_ptr, "true") )
|
||||
ptr[i].fill =1;
|
||||
ptr[i].fill = 1;
|
||||
else
|
||||
ptr[i].fill =0;
|
||||
ptr[i].fill = 0;
|
||||
dash = get_tok_value(ptr[i].prop_ptr,"dash",0);
|
||||
if(strcmp(dash, "")) {
|
||||
int d = atoi(dash);
|
||||
|
|
@ -2927,11 +2939,11 @@ static void load_box(FILE *fd)
|
|||
load_ascii_string( &ptr[i].prop_ptr, fd);
|
||||
fill_ptr = get_tok_value(ptr[i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
ptr[i].fill =3;
|
||||
ptr[i].fill = 2;
|
||||
else if( !strboolcmp(fill_ptr, "false") )
|
||||
ptr[i].fill =0;
|
||||
ptr[i].fill = 0;
|
||||
else
|
||||
ptr[i].fill =1;
|
||||
ptr[i].fill = 1;
|
||||
attr = get_tok_value(ptr[i].prop_ptr,"dash",0);
|
||||
if(strcmp(attr, "")) {
|
||||
int d = atoi(attr);
|
||||
|
|
@ -3532,7 +3544,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
|
|||
my_free(_ALLOC_ID_, &cmd);
|
||||
} else fd = NULL;
|
||||
}
|
||||
else fd=fopen(name,fopen_read_mode);
|
||||
else fd=my_fopen(name,fopen_read_mode);
|
||||
if( fd == NULL) {
|
||||
size_t len;
|
||||
ret = 0;
|
||||
|
|
@ -3545,7 +3557,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
|
|||
}
|
||||
len = strlen(name);
|
||||
if(!strcmp(name + len - 4, ".sym")) {
|
||||
xctx->save_netlist_type = xctx->netlist_type;
|
||||
if(xctx->netlist_type != CAD_SYMBOL_ATTRS) xctx->save_netlist_type = xctx->netlist_type;
|
||||
xctx->netlist_type = CAD_SYMBOL_ATTRS;
|
||||
set_tcl_netlist_type();
|
||||
xctx->loaded_symbol = 1;
|
||||
|
|
@ -3564,7 +3576,7 @@ int load_schematic(int load_symbols, const char *fname, int reset_undo, int aler
|
|||
if(reset_undo) {
|
||||
tclvareval("is_xschem_file {", xctx->sch[xctx->currsch], "}", NULL);
|
||||
if(!strcmp(tclresult(), "SYMBOL") || xctx->instances == 0) {
|
||||
xctx->save_netlist_type = xctx->netlist_type;
|
||||
if(xctx->netlist_type != CAD_SYMBOL_ATTRS) xctx->save_netlist_type = xctx->netlist_type;
|
||||
xctx->netlist_type = CAD_SYMBOL_ATTRS;
|
||||
set_tcl_netlist_type();
|
||||
xctx->loaded_symbol = 1;
|
||||
|
|
@ -3811,7 +3823,7 @@ void pop_undo(int redo, int set_modify_status)
|
|||
fd=fdopen(pd[0],"r");
|
||||
#else /* uncompressed undo */
|
||||
my_snprintf(diff_name, S(diff_name), "%s/undo%d", xctx->undo_dirname, xctx->cur_undo_ptr%MAX_UNDO);
|
||||
fd=fopen(diff_name, "r");
|
||||
fd=my_fopen(diff_name, fopen_read_mode);
|
||||
if(!fd) {
|
||||
fprintf(errfp, "pop_undo(): failed to open read pipe %s\n", diff_name);
|
||||
xctx->no_undo=1;
|
||||
|
|
@ -3882,9 +3894,9 @@ static void get_sym_type(const char *symname, char **type,
|
|||
if( !found ) {
|
||||
dbg(1, "get_sym_type(): open file %s, pintable %s\n",name, pintable ? "set" : "<NULL>");
|
||||
/* ... if not found open file and look for 'type' into the global attributes. */
|
||||
|
||||
|
||||
if(embed_fd) fd = embed_fd;
|
||||
else fd=fopen(name,fopen_read_mode);
|
||||
else fd=my_fopen(name,fopen_read_mode);
|
||||
|
||||
if(fd==NULL) {
|
||||
dbg(1, "get_sym_type(): Symbol not found: %s\n",name);
|
||||
|
|
@ -4226,15 +4238,15 @@ int load_sym_def(const char *name, FILE *embed_fd)
|
|||
} else {
|
||||
my_strncpy(sympath, abs_sym_path(transl_name, ""), S(sympath));
|
||||
}
|
||||
if((lcc[level].fd=fopen(sympath,fopen_read_mode))==NULL) {
|
||||
if((lcc[level].fd=my_fopen(sympath,fopen_read_mode))==NULL) {
|
||||
/* not found: try web URL */
|
||||
if(is_from_web(xctx->current_dirname)) {
|
||||
my_snprintf(sympath, S(sympath), "%s/%s", xschem_web_dirname, get_cell_w_ext(transl_name, 0));
|
||||
if((lcc[level].fd=fopen(sympath,fopen_read_mode))==NULL) {
|
||||
if((lcc[level].fd=my_fopen(sympath,fopen_read_mode))==NULL) {
|
||||
/* not already cached in .../xschem_web_xxxxx/ so download */
|
||||
tclvareval("try_download_url {", xctx->current_dirname, "} {", transl_name, "}", NULL);
|
||||
}
|
||||
lcc[level].fd=fopen(sympath,fopen_read_mode);
|
||||
lcc[level].fd=my_fopen(sympath,fopen_read_mode);
|
||||
}
|
||||
}
|
||||
dbg(1, "l_s_d(): fopen1(%s), level=%d, fd=%p\n",sympath, level, lcc[level].fd);
|
||||
|
|
@ -4246,7 +4258,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
|
|||
/* issue warning only on top level symbol loading */
|
||||
if(recursion_counter == 1) dbg(0, "l_s_d(): Symbol not found: %s\n", transl_name);
|
||||
my_snprintf(sympath, S(sympath), "%s/%s", tclgetvar("XSCHEM_SHAREDIR"), "systemlib/missing.sym");
|
||||
if((lcc[level].fd=fopen(sympath, fopen_read_mode))==NULL)
|
||||
if((lcc[level].fd=my_fopen(sympath, fopen_read_mode))==NULL)
|
||||
{
|
||||
fprintf(errfp, "l_s_d(): systemlib/missing.sym missing, I give up\n");
|
||||
tcleval("exit");
|
||||
|
|
@ -4441,11 +4453,11 @@ int load_sym_def(const char *name, FILE *embed_fd)
|
|||
|
||||
fill_ptr = get_tok_value(pp[c][i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
pp[c][i].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
pp[c][i].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if( !strboolcmp(fill_ptr, "true") )
|
||||
pp[c][i].fill =1;
|
||||
pp[c][i].fill = 1;
|
||||
else
|
||||
pp[c][i].fill =0;
|
||||
pp[c][i].fill = 0;
|
||||
|
||||
attr = get_tok_value(pp[c][i].prop_ptr,"dash", 0);
|
||||
if( strcmp(attr, "") ) {
|
||||
|
|
@ -4507,11 +4519,11 @@ int load_sym_def(const char *name, FILE *embed_fd)
|
|||
}
|
||||
fill_ptr = get_tok_value(aa[c][i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
aa[c][i].fill =3; /* bit 1: solid fill (not stiaaled) */
|
||||
aa[c][i].fill = 2; /* bit 1: solid fill (not stiaaled) */
|
||||
else if( !strboolcmp(fill_ptr, "true") )
|
||||
aa[c][i].fill =1;
|
||||
aa[c][i].fill = 1;
|
||||
else
|
||||
aa[c][i].fill =0;
|
||||
aa[c][i].fill = 0;
|
||||
attr = get_tok_value(aa[c][i].prop_ptr,"dash", 0);
|
||||
if( strcmp(attr, "") ) {
|
||||
int d = atoi(attr);
|
||||
|
|
@ -4570,11 +4582,11 @@ int load_sym_def(const char *name, FILE *embed_fd)
|
|||
dbg(2, "l_s_d(): loaded rect: ptr=%lx\n", (unsigned long)bb[c]);
|
||||
fill_ptr = get_tok_value(bb[c][i].prop_ptr,"fill",0);
|
||||
if( !strcmp(fill_ptr, "full") )
|
||||
bb[c][i].fill =3;
|
||||
bb[c][i].fill = 2;
|
||||
else if( !strboolcmp(fill_ptr, "false") )
|
||||
bb[c][i].fill =0;
|
||||
bb[c][i].fill = 0;
|
||||
else
|
||||
bb[c][i].fill =1;
|
||||
bb[c][i].fill = 1;
|
||||
attr = get_tok_value(bb[c][i].prop_ptr,"dash", 0);
|
||||
if( strcmp(attr, "") ) {
|
||||
int d = atoi(attr);
|
||||
|
|
@ -4787,6 +4799,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
|
|||
dbg(1, "l_s_d(): level=%d, symname=%s symtype=%s\n", level, symname, symtype);
|
||||
|
||||
if( /* add here symbol types not to consider when loading schematic-as-symbol instances */
|
||||
!symtype ||
|
||||
!strcmp(symtype, "logo") ||
|
||||
!strcmp(symtype, "netlist_commands") ||
|
||||
!strcmp(symtype, "netlist_options") ||
|
||||
|
|
@ -4817,7 +4830,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
|
|||
|
||||
dbg(1, "l_s_d(): fopen2(%s), level=%d\n",sympath, level);
|
||||
/* find out if symbol is in an external file or embedded, set fd_tmp accordingly */
|
||||
if ((fd_tmp = fopen(sympath, fopen_read_mode)) == NULL) {
|
||||
if ((fd_tmp = my_fopen(sympath, fopen_read_mode)) == NULL) {
|
||||
char c;
|
||||
fprintf(errfp, "l_s_d(): unable to open file to read schematic: %s\n", sympath);
|
||||
if(!generator) {
|
||||
|
|
@ -5107,6 +5120,7 @@ int descend_symbol(void)
|
|||
char name_embedded[PATH_MAX];
|
||||
int n = 0;
|
||||
struct stat buf;
|
||||
int save_netlist_type = xctx->netlist_type;
|
||||
if(xctx->currsch + 1 >= CADMAXHIER) {
|
||||
dbg(0, "descend_symbol(): max hierarchy depth reached: %d", CADMAXHIER);
|
||||
return 0;
|
||||
|
|
@ -5216,6 +5230,10 @@ int descend_symbol(void)
|
|||
}
|
||||
my_free(_ALLOC_ID_, &sympath);
|
||||
}
|
||||
if(save_netlist_type != CAD_SYMBOL_ATTRS) xctx->save_netlist_type = save_netlist_type;
|
||||
xctx->loaded_symbol = 1;
|
||||
xctx->netlist_type = CAD_SYMBOL_ATTRS;
|
||||
set_tcl_netlist_type();
|
||||
zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1344,6 +1344,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
my_snprintf(res, S(res), "%g %g %g %g", boundbox.x1, boundbox.y1, boundbox.x2, boundbox.y2);
|
||||
Tcl_SetResult(interp, res, TCL_VOLATILE);
|
||||
}
|
||||
else if(!strcmp(argv[2], "build_date")) { /* time and date this file was built. */
|
||||
char date[] = __DATE__ " : " __TIME__;
|
||||
Tcl_SetResult(interp, date, TCL_STATIC);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
if(!strcmp(argv[2], "cadlayers")) { /* number of layers */
|
||||
|
|
@ -2158,7 +2162,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
if(argc > 2 ) {
|
||||
what = atoi(argv[2]);
|
||||
}
|
||||
if((xctx->semaphore == 0)) go_back(what);
|
||||
if(xctx->semaphore == 0) go_back(what);
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
|
|
@ -3024,6 +3028,33 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
else if(argc==2 && errfp != stderr) { fclose(errfp); errfp=stderr; }
|
||||
}
|
||||
|
||||
/* load_symbol [symbol_file]
|
||||
* Load specified symbol_file
|
||||
* Returns:
|
||||
* >= 0: symbol is already loaded or has been loaded
|
||||
* < 0: symbol was not loaded
|
||||
*/
|
||||
else if(!strcmp(argv[1], "load_symbol") )
|
||||
{
|
||||
int res = -2;
|
||||
struct stat buf;
|
||||
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
|
||||
if(argc > 2) {
|
||||
int i = get_symbol(rel_sym_path(argv[2]));
|
||||
if(i < 0 ) {
|
||||
if(!stat(argv[2], &buf)) { /* file exists */
|
||||
res = load_sym_def(rel_sym_path(argv[2]), NULL);
|
||||
if(res == 0) res = -1;
|
||||
} else {
|
||||
res = -3;
|
||||
}
|
||||
} else {
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
Tcl_SetResult(interp, my_itoa(res), TCL_VOLATILE);
|
||||
}
|
||||
|
||||
/* log_write text
|
||||
* write given string to log file, so tcl can write messages on the log file
|
||||
*/
|
||||
|
|
@ -3356,7 +3387,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
"-message {Please Set netlisting mode (Options menu)}");
|
||||
tclsetboolvar("keep_symbols", save_keep);
|
||||
|
||||
if( (erc == 0) ) {
|
||||
if(erc == 0) {
|
||||
my_strncpy(xctx->netlist_name, "", S(xctx->netlist_name));
|
||||
}
|
||||
}
|
||||
|
|
@ -5547,7 +5578,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
set_rect_flags(r); /* set cached .flags bitmask from attributes */
|
||||
if(argc > 5 && !strcmp(argv[5], "fill")) {
|
||||
const char *attr = get_tok_value(r->prop_ptr,"fill", 0);
|
||||
if(!strcmp(attr, "full")) xctx->rect[c][n].fill = 3;
|
||||
if(!strcmp(attr, "full")) xctx->rect[c][n].fill = 2;
|
||||
else if(!strboolcmp(attr, "false")) xctx->rect[c][n].fill = 0;
|
||||
else xctx->rect[c][n].fill = 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ static void del_rect_line_arc_poly()
|
|||
{
|
||||
++j;
|
||||
|
||||
if(xctx->arc[c][i].fill & 1) /* .fill: 1: stippled fill, 3: solid fill */
|
||||
if(xctx->arc[c][i].fill) /* .fill: 1: stippled fill, 2: solid fill */
|
||||
arc_bbox(xctx->arc[c][i].x, xctx->arc[c][i].y, xctx->arc[c][i].r, 0, 360,
|
||||
&tmp.x1, &tmp.y1, &tmp.x2, &tmp.y2);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -635,6 +635,11 @@ int spice_block_netlist(FILE *fd, int i, int alert)
|
|||
tclgetvar("netlist_dir"), get_cell(name, 0), getpid());
|
||||
dbg(1, "spice_block_netlist(): split_files: netl_filename=%s\n", netl_filename);
|
||||
fd=fopen(netl_filename, "w");
|
||||
if(!fd) {
|
||||
dbg(0, "spice_block_netlist(): unable to write file %s\n", netl_filename);
|
||||
err = 1;
|
||||
goto err;
|
||||
}
|
||||
my_snprintf(cellname, S(cellname), "%s.spice", get_cell(name, 0));
|
||||
}
|
||||
fprintf(fd, "\n* expanding symbol: %s # of pins=%d\n", name,xctx->sym[i].rects[PINLAYER] );
|
||||
|
|
@ -689,6 +694,7 @@ int spice_block_netlist(FILE *fd, int i, int alert)
|
|||
set_tcl_netlist_type();
|
||||
if(debug_var==0) xunlink(netl_filename);
|
||||
}
|
||||
err:
|
||||
xctx->netlist_count++;
|
||||
my_free(_ALLOC_ID_, &name);
|
||||
return err;
|
||||
|
|
|
|||
18
src/store.c
18
src/store.c
|
|
@ -156,11 +156,11 @@ void store_arc(int pos, double x, double y, double r, double a, double b,
|
|||
|
||||
fill_ptr = get_tok_value(xctx->arc[rectc][n].prop_ptr,"fill",0);
|
||||
if(!strcmp(fill_ptr, "full") )
|
||||
xctx->arc[rectc][n].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
xctx->arc[rectc][n].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if(!strboolcmp(fill_ptr, "true") )
|
||||
xctx->arc[rectc][n].fill =1;
|
||||
xctx->arc[rectc][n].fill = 1;
|
||||
else
|
||||
xctx->arc[rectc][n].fill =0;
|
||||
xctx->arc[rectc][n].fill = 0;
|
||||
dash = get_tok_value(xctx->arc[rectc][n].prop_ptr,"dash",0);
|
||||
if( strcmp(dash, "") ) {
|
||||
int d = atoi(dash);
|
||||
|
|
@ -206,11 +206,11 @@ void store_poly(int pos, double *x, double *y, int points, unsigned int rectc,
|
|||
|
||||
fill_ptr = get_tok_value(xctx->poly[rectc][n].prop_ptr,"fill",0);
|
||||
if(!strcmp(fill_ptr, "full") )
|
||||
xctx->poly[rectc][n].fill =3; /* bit 1: solid fill (not stippled) */
|
||||
xctx->poly[rectc][n].fill = 2; /* bit 1: solid fill (not stippled) */
|
||||
else if(!strboolcmp(fill_ptr, "true") )
|
||||
xctx->poly[rectc][n].fill =1;
|
||||
xctx->poly[rectc][n].fill = 1;
|
||||
else
|
||||
xctx->poly[rectc][n].fill =0;
|
||||
xctx->poly[rectc][n].fill = 0;
|
||||
dash = get_tok_value(xctx->poly[rectc][n].prop_ptr,"dash",0);
|
||||
if( strcmp(dash, "") ) {
|
||||
int d = atoi(dash);
|
||||
|
|
@ -307,11 +307,11 @@ int storeobject(int pos, double x1,double y1,double x2,double y2,
|
|||
|
||||
fill_ptr = get_tok_value(xctx->rect[rectc][n].prop_ptr, "fill", 0);
|
||||
if(!strcmp(fill_ptr, "full") )
|
||||
xctx->rect[rectc][n].fill =3;
|
||||
xctx->rect[rectc][n].fill = 2;
|
||||
else if(!strboolcmp(fill_ptr,"false") )
|
||||
xctx->rect[rectc][n].fill =0;
|
||||
xctx->rect[rectc][n].fill = 0;
|
||||
else
|
||||
xctx->rect[rectc][n].fill =1;
|
||||
xctx->rect[rectc][n].fill = 1;
|
||||
set_rect_flags(&xctx->rect[rectc][n]); /* set cached .flags bitmask from on attributes */
|
||||
if(rectc == GRIDLAYER && (xctx->rect[rectc][n].flags & 1024)) {
|
||||
xRect *r = &xctx->rect[GRIDLAYER][n];
|
||||
|
|
|
|||
115
src/svgdraw.c
115
src/svgdraw.c
|
|
@ -62,7 +62,7 @@ static void svg_xfillrectangle(int layer, double x1, double y1, double x2, doubl
|
|||
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
|
||||
if(fill == 0) {
|
||||
fprintf(fd,"style=\"fill:none;\" ");
|
||||
} else if(fill == 3) {
|
||||
} else if(fill == 2) {
|
||||
fprintf(fd, "style=\"fill-opacity:1.0;\" ");
|
||||
}
|
||||
fprintf(fd,"d=\"M%g %gL%g %gL%g %gL%g %gL%g %gz\"/>\n", x1, y1, x2, y1, x2, y2, x1, y2, x1, y1);
|
||||
|
|
@ -135,7 +135,7 @@ static void svg_drawpolygon(int c, int what, double *x, double *y, int points, i
|
|||
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
|
||||
if(fill == 0) {
|
||||
fprintf(fd,"style=\"fill:none;\" ");
|
||||
} else if(fill == 3) {
|
||||
} else if(fill == 2) {
|
||||
fprintf(fd, "style=\"fill-opacity:1.0;\" ");
|
||||
}
|
||||
bezier = flags && (points > 2);
|
||||
|
|
@ -154,7 +154,8 @@ static void svg_drawpolygon(int c, int what, double *x, double *y, int points, i
|
|||
fprintf(fd, "\"/>\n");
|
||||
}
|
||||
|
||||
static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2, int dash, int fill)
|
||||
static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,double recty2,
|
||||
int dash, int fill, int e_a, int e_b)
|
||||
{
|
||||
double x1,y1,x2,y2;
|
||||
|
||||
|
|
@ -164,7 +165,41 @@ static void svg_filledrect(int gc, double rectx1,double recty1,double rectx2,dou
|
|||
y2=Y_TO_SCREEN(recty2);
|
||||
if( rectclip(xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2,&x1,&y1,&x2,&y2) )
|
||||
{
|
||||
svg_xfillrectangle(gc, x1,y1,x2,y2, dash, fill);
|
||||
if(e_a != -1) {
|
||||
double rx = (x2 - x1) / 2.0;
|
||||
double ry = (y2 - y1) / 2.0;
|
||||
double cx = (x2 + x1) / 2.0;
|
||||
double cy = (y2 + y1) / 2.0;
|
||||
|
||||
if(e_b == 360.) {
|
||||
fprintf(fd, "<ellipse class=\"l%d\" cx=\"%g\" cy=\"%g\" rx=\"%g\" ry=\"%g\" ", gc, cx, cy, rx, ry);
|
||||
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
|
||||
if(fill == 0) fprintf(fd, "style=\"fill:none;\" ");
|
||||
else if(fill == 2) fprintf(fd, "style=\"fill-opacity:1.0;\" ");
|
||||
fprintf(fd, "/>\n");
|
||||
} else {
|
||||
double xx1 = rx * cos(e_a * XSCH_PI / 180.) + cx;
|
||||
double yy1 = -ry * sin(e_a * XSCH_PI / 180.) + cy;
|
||||
double xx2 = rx * cos((e_a + e_b) * XSCH_PI / 180.) + cx;
|
||||
double yy2 = -ry * sin((e_a + e_b) * XSCH_PI / 180.) + cy;
|
||||
int fa = e_b > 180 ? 1 : 0;
|
||||
int fs = e_b > 0 ? 0 : 1;
|
||||
|
||||
fprintf(fd,"<path class=\"l%d\" ", gc);
|
||||
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
|
||||
if(fill == 0) {
|
||||
fprintf(fd,"style=\"fill:none;\" ");
|
||||
fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %g\"/>\n", xx1, yy1, rx, ry, fa, fs, xx2, yy2);
|
||||
} else if(fill == 2) {
|
||||
fprintf(fd, "style=\"fill-opacity:1.0;\" ");
|
||||
fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rx, ry, fa, fs, xx2, yy2, cx, cy);
|
||||
} else {
|
||||
fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rx, ry, fa, fs, xx2, yy2, cx, cy);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
svg_xfillrectangle(gc, x1,y1,x2,y2, dash, fill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -210,7 +245,7 @@ static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a
|
|||
fprintf(fd, "<circle class=\"l%d\" cx=\"%g\" cy=\"%g\" r=\"%g\" ", gc, xx, yy, rr);
|
||||
if(dash) fprintf(fd, "stroke-dasharray=\"%g,%g\" ", 1.4*dash/xctx->zoom, 1.4*dash/xctx->zoom);
|
||||
if(fillarc == 0) fprintf(fd, "style=\"fill:none;\" ");
|
||||
else if(fillarc == 3) fprintf(fd, "style=\"fill-opacity:1.0;\" ");
|
||||
else if(fillarc == 2) fprintf(fd, "style=\"fill-opacity:1.0;\" ");
|
||||
|
||||
fprintf(fd, "/>\n");
|
||||
} else {
|
||||
|
|
@ -226,12 +261,12 @@ static void svg_drawarc(int gc, int fillarc, double x,double y,double r,double a
|
|||
if(fillarc == 0) {
|
||||
fprintf(fd,"style=\"fill:none;\" ");
|
||||
fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %g\"/>\n", xx1, yy1, rr, rr, fa, fs, xx2, yy2);
|
||||
} else if(fillarc == 3) {
|
||||
} else if(fillarc == 2) {
|
||||
fprintf(fd, "style=\"fill-opacity:1.0;\" ");
|
||||
fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rr, rr, fa, fs, xx2, yy2, xx, yy);
|
||||
} else {
|
||||
fprintf(fd, "d=\"M%g %g A%g %g 0 %d %d %g %gL%g %gz\"/>\n", xx1, yy1, rr, rr, fa, fs, xx2, yy2, xx, yy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -478,6 +513,7 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub
|
|||
double alpha = 1.0;
|
||||
unsigned char *buffer = NULL;
|
||||
size_t buffer_size;
|
||||
double xorig, yorig; /* image anchor point, upper left corner in SVG */
|
||||
|
||||
x1=X_TO_SCREEN(rx1);
|
||||
y1=Y_TO_SCREEN(ry1);
|
||||
|
|
@ -488,7 +524,6 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub
|
|||
if(RECT_OUTSIDE(x1, y1, x2, y2,
|
||||
xctx->areax1,xctx->areay1,xctx->areax2,xctx->areay2)) return 0;
|
||||
|
||||
|
||||
if(rot == 1 || rot == 3) {
|
||||
w = fabs(y2 - y1);
|
||||
h = fabs(x2 - x1);
|
||||
|
|
@ -498,7 +533,8 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub
|
|||
}
|
||||
|
||||
if(flip && (rot == 0 || rot == 2)) scalex = -1.0;
|
||||
else if(flip && (rot == 1 || rot == 3)) scaley = -1.0;
|
||||
else if(flip && (rot == 1 || rot == 3)) scalex = -1.0;
|
||||
|
||||
alpha_str = get_tok_value(r->prop_ptr, "alpha", 0);
|
||||
if(alpha_str[0]) alpha = atof(alpha_str);
|
||||
attr_len = my_strdup2(_ALLOC_ID_, &attr, get_tok_value(r->prop_ptr, "image_data", 0));
|
||||
|
|
@ -523,8 +559,32 @@ static int svg_embedded_image(xRect *r, double rx1, double ry1, double rx2, doub
|
|||
my_free(_ALLOC_ID_, &attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
xorig = x1;
|
||||
yorig = y1;
|
||||
if(rot == 0) {
|
||||
if(flip) xorig += w;
|
||||
} else if(rot == 1) {
|
||||
if(flip) {
|
||||
xorig += h;
|
||||
yorig += w;
|
||||
} else xorig += h;
|
||||
} else if(rot == 2) {
|
||||
if(flip) {
|
||||
yorig += h;
|
||||
} else {
|
||||
xorig += w;
|
||||
yorig += h;
|
||||
}
|
||||
} else if(rot == 3) {
|
||||
if(flip) {
|
||||
} else {
|
||||
yorig += w;
|
||||
}
|
||||
}
|
||||
|
||||
my_snprintf(transform, S(transform),
|
||||
"transform=\"translate(%g,%g) scale(%g,%g) rotate(%d)\"", x1, y1, scalex, scaley, rot * 90);
|
||||
"transform=\"translate(%g,%g) rotate(%d) scale(%g,%g)\"", xorig, yorig, rot * 90, scalex, scaley);
|
||||
if(alpha == 1.0) strcpy(opacity, "");
|
||||
else my_snprintf(opacity, S(opacity), "style=\"opacity:%g;\"", alpha);
|
||||
/* png jpg */
|
||||
|
|
@ -603,7 +663,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
|
|||
}
|
||||
else if((xctx->inst[n].x2 - xctx->inst[n].x1) * xctx->mooz < 3 &&
|
||||
(xctx->inst[n].y2 - xctx->inst[n].y1) * xctx->mooz < 3) {
|
||||
svg_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0);
|
||||
svg_filledrect(c, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 0, 0, -1, -1);
|
||||
xctx->inst[n].flags|=1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -612,7 +672,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
|
|||
}
|
||||
if(hide) {
|
||||
int color = (disabled==1) ? GRIDLAYER : (disabled == 2) ? PINLAYER : SYMLAYER;
|
||||
svg_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0);
|
||||
svg_filledrect(color, xctx->inst[n].xx1, xctx->inst[n].yy1, xctx->inst[n].xx2, xctx->inst[n].yy2, 2, 0, -1, -1);
|
||||
}
|
||||
}
|
||||
else if(xctx->inst[n].flags&1) {
|
||||
|
|
@ -692,9 +752,27 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
|
|||
double xx2 = x0 + x2;
|
||||
double yy2 = y0 + y2;
|
||||
svg_embedded_image(rect, xx1, yy1, xx2, yy2, rot, flip);
|
||||
continue;
|
||||
} else {
|
||||
int ellipse_a = rect->ellipse_a;
|
||||
int ellipse_b = rect->ellipse_b;
|
||||
|
||||
if(ellipse_a != -1 && ellipse_b != 360) {
|
||||
if(flip) {
|
||||
ellipse_a = 180 - ellipse_a - ellipse_b;
|
||||
}
|
||||
if(rot) {
|
||||
if(rot == 3) {
|
||||
ellipse_a += 90;
|
||||
} else if(rot == 2) {
|
||||
ellipse_a += 180;
|
||||
} else if(rot == 1) {
|
||||
ellipse_a += 270;
|
||||
}
|
||||
ellipse_a %= 360;
|
||||
}
|
||||
}
|
||||
svg_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill, ellipse_a, ellipse_b);
|
||||
}
|
||||
svg_filledrect(c, x0+x1, y0+y1, x0+x2, y0+y2, dash, rect->fill);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -916,8 +994,8 @@ void svg_draw(void)
|
|||
* 2 : solid fill
|
||||
* fill_type[i]:
|
||||
* 0 : no fill
|
||||
* 1 : solid fill
|
||||
* 2 : patterned (stippled) fill
|
||||
* 1 : patterned (stippled) fill
|
||||
* 2 : solid fill
|
||||
*/
|
||||
for(i=0;i<cadlayers; ++i){
|
||||
if(unused_layer[i]) continue;
|
||||
|
|
@ -927,7 +1005,7 @@ void svg_draw(void)
|
|||
svg_colors[i].red, svg_colors[i].green, svg_colors[i].blue);
|
||||
else if( xctx->fill_pattern == 2 && xctx->fill_type[i])
|
||||
fprintf(fd, " fill: #%02x%02x%02x;\n", svg_colors[i].red, svg_colors[i].green, svg_colors[i].blue);
|
||||
else if( xctx->fill_pattern && xctx->fill_type[i] == 1)
|
||||
else if( xctx->fill_pattern && xctx->fill_type[i] == 2)
|
||||
fprintf(fd, " fill: #%02x%02x%02x;\n", svg_colors[i].red, svg_colors[i].green, svg_colors[i].blue);
|
||||
else
|
||||
fprintf(fd, " fill: #%02x%02x%02x; fill-opacity: 0.5;\n",
|
||||
|
|
@ -976,7 +1054,8 @@ void svg_draw(void)
|
|||
} else {
|
||||
svg_filledrect(c, xctx->rect[c][i].x1, xctx->rect[c][i].y1,
|
||||
xctx->rect[c][i].x2, xctx->rect[c][i].y2,
|
||||
xctx->rect[c][i].dash, xctx->rect[c][i].fill);
|
||||
xctx->rect[c][i].dash, xctx->rect[c][i].fill,
|
||||
xctx->rect[c][i].ellipse_a, xctx->rect[c][i].ellipse_b);
|
||||
}
|
||||
}
|
||||
for(i=0;i<xctx->arcs[c]; ++i)
|
||||
|
|
|
|||
135
src/token.c
135
src/token.c
|
|
@ -1174,26 +1174,41 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist primitives, 200
|
|||
|
||||
if(c=='\0')
|
||||
{
|
||||
/* do one level of substitutions to resolve remaining @params and/or tcl expr/code */
|
||||
if(result) {
|
||||
dbg(1, "print_vhdl_primitive(): before translate() result=%s\n", result);
|
||||
if(!strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) {
|
||||
/* since netlist_commands often have @ characters in spice node save / plot commands, do
|
||||
* not pass through translate, unless a tcleval(...) is present */
|
||||
if(strstr(result, "tcleval(")== result) {
|
||||
my_strdup(_ALLOC_ID_, &result, translate(inst, result));
|
||||
}
|
||||
} else {
|
||||
my_strdup(_ALLOC_ID_, &result, translate(inst, result));
|
||||
}
|
||||
dbg(1, "print_vhdl_primitive(): after translate() result=%s\n", result);
|
||||
}
|
||||
if(result) fprintf(fd, "%s", result);
|
||||
fputc('\n',fd);
|
||||
fprintf(fd, "---- end primitive\n");
|
||||
break ;
|
||||
char *parent_prop_ptr = NULL;
|
||||
|
||||
if(xctx->currsch > 0) {
|
||||
parent_prop_ptr = xctx->hier_attr[xctx->currsch - 1].prop_ptr;
|
||||
}
|
||||
/* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions
|
||||
* can be calculated. Before that do also a round of translation to remove remaining @params */
|
||||
if(result) {
|
||||
dbg(1, "print_vhdl_primitive(): before translate3() result=%s\n", result);
|
||||
if(strchr(result, '@')) {
|
||||
/* netlist_commands often have @ characters due to ngspice syntax. Do not translate */
|
||||
if(strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) {
|
||||
my_strdup2(_ALLOC_ID_, &result,
|
||||
translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL));
|
||||
/* can not put template in above translate3: -----------------------^^^^
|
||||
* if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3
|
||||
* we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */
|
||||
if(strchr(result, '@')) {
|
||||
my_strdup2(_ALLOC_ID_, &result,
|
||||
translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
|
||||
if(strstr(result, "expr(") ) {
|
||||
result = eval_expr(result);
|
||||
}
|
||||
dbg(1, "print_vhdl_primitive(): after translate3() result=%s\n", result);
|
||||
}
|
||||
if(result) fprintf(fd, "%s", result);
|
||||
fputc('\n',fd);
|
||||
fprintf(fd, "---- end primitive\n");
|
||||
break ;
|
||||
}
|
||||
}
|
||||
} /* while(1) */
|
||||
my_free(_ALLOC_ID_, &result);
|
||||
my_free(_ALLOC_ID_, &template);
|
||||
my_free(_ALLOC_ID_, &format);
|
||||
|
|
@ -2398,7 +2413,14 @@ int print_spice_element(FILE *fd, int inst)
|
|||
* model=nfet_01v8
|
||||
*/
|
||||
my_strdup2(_ALLOC_ID_, &val,
|
||||
translate3(token, 2, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL));
|
||||
translate3(token, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL));
|
||||
/* can not put template in above translate3: ---------------------------^^^^
|
||||
* if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3
|
||||
* we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */
|
||||
if(strchr(val, '@')) {
|
||||
my_strdup2(_ALLOC_ID_, &val,
|
||||
translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL));
|
||||
}
|
||||
/* nmos instance format string: @model --> @modeln */
|
||||
dbg(1, "print_spice_element(): 1st round: val: |%s|\n", val);
|
||||
if(strchr(val, '@')) {
|
||||
|
|
@ -2428,12 +2450,10 @@ int print_spice_element(FILE *fd, int inst)
|
|||
}
|
||||
dbg(1, "print_spice_element(): final: val: |%s|\n", val);
|
||||
}
|
||||
value = val;
|
||||
/* xctx->tok_size==0 (set in translate3()) indicates that token(+1) does not exist
|
||||
* in instance attributes so try to get from symbol template */
|
||||
dbg(1, "print_spice_element(): val: %s\n", val);
|
||||
/* still unresolved: set to empty */
|
||||
if(val[0] == '@') value = "";
|
||||
else value = val;
|
||||
token_exists = xctx->tok_size;
|
||||
value = val;
|
||||
tok_val_len = strlen(value);
|
||||
/* @spiceprefix needs a special tag for postprocessing */
|
||||
if(!strcmp(token, "@spiceprefix") && value[0]) {
|
||||
|
|
@ -3109,26 +3129,42 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level
|
|||
}
|
||||
if(c=='\0')
|
||||
{
|
||||
/* do one level of substitutions to resolve remaining @params and/or tcl expr/code */
|
||||
char *parent_prop_ptr = NULL;
|
||||
|
||||
if(xctx->currsch > 0) {
|
||||
parent_prop_ptr = xctx->hier_attr[xctx->currsch - 1].prop_ptr;
|
||||
}
|
||||
|
||||
/* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions
|
||||
* can be calculated. Before that do also a round of translation to remove remaining @params */
|
||||
if(result) {
|
||||
dbg(1, "print_verilog_primitive(): before translate() result=%s\n", result);
|
||||
if(!strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) {
|
||||
/* since netlist_commands often have @ characters in spice node save / plot commands, do
|
||||
* not pass through translate, unless a tcleval(...) is present */
|
||||
if(strstr(result, "tcleval(")== result) {
|
||||
my_strdup(_ALLOC_ID_, &result, translate(inst, result));
|
||||
dbg(1, "print_verilog_primitive(): before translate3() result=%s\n", result);
|
||||
if(strchr(result, '@')) {
|
||||
/* netlist_commands often have @ characters due to ngspice syntax. Do not translate */
|
||||
if(strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) {
|
||||
my_strdup2(_ALLOC_ID_, &result,
|
||||
translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL));
|
||||
/* can not put template in above translate3: -----------------------^^^^
|
||||
* if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3
|
||||
* we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */
|
||||
if(strchr(result, '@')) {
|
||||
my_strdup2(_ALLOC_ID_, &result,
|
||||
translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my_strdup(_ALLOC_ID_, &result, translate(inst, result));
|
||||
}
|
||||
dbg(1, "print_verilog_primitive(): after translate() result=%s\n", result);
|
||||
my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */
|
||||
if(strstr(result, "expr(") ) {
|
||||
result = eval_expr(result);
|
||||
}
|
||||
dbg(1, "print_verilog_primitive(): after translate3() result=%s\n", result);
|
||||
}
|
||||
if(result) fprintf(fd, "%s", result);
|
||||
fputc('\n',fd);
|
||||
fprintf(fd, "---- end primitive\n");
|
||||
break ;
|
||||
}
|
||||
}
|
||||
} /* while(1) */
|
||||
my_free(_ALLOC_ID_, &result);
|
||||
my_free(_ALLOC_ID_, &template);
|
||||
my_free(_ALLOC_ID_, &format);
|
||||
|
|
@ -3748,7 +3784,9 @@ const char *spice_get_node(const char *token)
|
|||
/* if s==NULL return emty string */
|
||||
const char *translate(int inst, const char* s)
|
||||
{
|
||||
#ifdef __unix__
|
||||
static regex_t *get_sp_cur = NULL;
|
||||
#endif
|
||||
static const char *empty="";
|
||||
static char *result=NULL; /* safe to keep even with multiple schematics */
|
||||
size_t size=0;
|
||||
|
|
@ -3773,24 +3811,28 @@ const char *translate(int inst, const char* s)
|
|||
|
||||
if(!s && inst == -1) {
|
||||
if(result) my_free(_ALLOC_ID_, &result);
|
||||
#ifdef __unix__
|
||||
if(get_sp_cur) {
|
||||
regfree(get_sp_cur);
|
||||
get_sp_cur = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if(!s || !xctx || !xctx->inst) {
|
||||
return empty;
|
||||
}
|
||||
|
||||
#ifdef __unix__
|
||||
if(!get_sp_cur) {
|
||||
get_sp_cur = my_malloc(_ALLOC_ID_, sizeof(regex_t));
|
||||
/* @spice_get_current_param(...) or @spice_get_modelparam_param(...) */
|
||||
/* @spice_get_current_<param>(...) or @spice_get_modelparam_<param>(...) */
|
||||
/* @spice_get_current(...) or @spice_get_modelparam(...) */
|
||||
/* @spice_get_modelvoltage(...) or @spice_get_modelvoltage_param(...) */
|
||||
/* @spice_get_modelvoltage(...) or @spice_get_modelvoltage_<param>(...) */
|
||||
regcomp(get_sp_cur,
|
||||
"^@spice_get_(current|modelparam|modelvoltage)(_[a-zA-Z][a-zA-Z0-9_]*)*\\(", REG_NOSUB | REG_EXTENDED);
|
||||
}
|
||||
#endif
|
||||
|
||||
sp_prefix = tclgetboolvar("spiceprefix");
|
||||
|
||||
|
|
@ -4116,13 +4158,17 @@ const char *translate(int inst, const char* s)
|
|||
}
|
||||
}
|
||||
}
|
||||
/* @spice_get_current(...) or @spice_get_current_param(...)
|
||||
* @spice_get_modelparam(...) or @spice_get_modelparam_param(...)
|
||||
* @spice_get_modelvoltage(...) or @spice_get_modelvoltage_param(...)
|
||||
/* @spice_get_current(...) or @spice_get_current_<param>(...)
|
||||
* @spice_get_modelparam(...) or @spice_get_modelparam_<param>(...)
|
||||
* @spice_get_modelvoltage(...) or @spice_get_modelvoltage_<param>(...)
|
||||
*
|
||||
* Only @spice_get_current(...) and @spice_get_current_param(...) are processed
|
||||
* Only @spice_get_current(...) and @spice_get_current_<param>(...) are processed
|
||||
* the other types are ignored */
|
||||
#ifdef __unix__
|
||||
else if(!regexec(get_sp_cur, token, 0 , NULL, 0) )
|
||||
# else
|
||||
else if ((win_regexec(NULL/*options*/, "^@spice_get_(current|modelparam|modelvoltage)(_[a-zA-Z][a-zA-Z0-9_]*)*\\(", token)))
|
||||
#endif
|
||||
{
|
||||
int start_level; /* hierarchy level where waves were loaded */
|
||||
int live = tclgetboolvar("live_cursor2_backannotate");
|
||||
|
|
@ -4148,7 +4194,8 @@ const char *translate(int inst, const char* s)
|
|||
n = sscanf(token + 19, "%[^)]", dev);
|
||||
} else {
|
||||
param = my_malloc(_ALLOC_ID_, tmp);
|
||||
n = sscanf(token, "@spice_get_current_%s(%[^)]", param, dev);
|
||||
n = sscanf(token, "@spice_get_current_%[^(](%[^)]", param, dev);
|
||||
dbg(1, "token=%s, param=%s, dev=%s\n", token, param, dev);
|
||||
if(n < 2) {
|
||||
my_free(_ALLOC_ID_, ¶m);
|
||||
n = sscanf(token, "@spice_get_current[^(](%[^)]", dev);
|
||||
|
|
@ -4173,6 +4220,7 @@ const char *translate(int inst, const char* s)
|
|||
my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, param ? param : "ic");
|
||||
} else if(prefix == 'd' || prefix == 'm') {
|
||||
my_snprintf(fqdev, len, "i(@%c.%s%s.%s[%s])", prefix, path, instname, dev, param ? param : "id");
|
||||
dbg(1, "translate(): fqdev=%s\n", fqdev);
|
||||
} else if(prefix == 'i') {
|
||||
my_snprintf(fqdev, len, "i(@%c.%s%s.%s[current])", prefix, path, instname, dev);
|
||||
} else {
|
||||
|
|
@ -4605,7 +4653,6 @@ const char *translate2(Lcc *lcc, int level, char* s)
|
|||
}
|
||||
else if(strcmp(token,"@path")==0) {
|
||||
char *path = NULL;
|
||||
here(level);
|
||||
my_strdup2(_ALLOC_ID_, &path, "@path@name\\.");
|
||||
if(level > 1) { /* add parent LCC instance names (X1, Xinv etc) */
|
||||
int i;
|
||||
|
|
|
|||
|
|
@ -453,6 +453,11 @@ int verilog_block_netlist(FILE *fd, int i, int alert)
|
|||
tclgetvar("netlist_dir"), get_cell(name, 0), getpid());
|
||||
dbg(1, "global_vhdl_netlist(): split_files: netl_filename=%s\n", netl_filename);
|
||||
fd=fopen(netl_filename, "w");
|
||||
if(!fd) {
|
||||
dbg(0, "verilog_block_netlist(): unable to write file %s\n", netl_filename);
|
||||
err = 1;
|
||||
goto err;
|
||||
}
|
||||
my_snprintf(cellname, S(cellname), "%s.v", get_cell(name, 0));
|
||||
|
||||
}
|
||||
|
|
@ -619,6 +624,7 @@ int verilog_block_netlist(FILE *fd, int i, int alert)
|
|||
set_tcl_netlist_type();
|
||||
if(debug_var==0) xunlink(netl_filename);
|
||||
}
|
||||
err:
|
||||
xctx->netlist_count++;
|
||||
my_free(_ALLOC_ID_, &name);
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -538,6 +538,11 @@ int vhdl_block_netlist(FILE *fd, int i, int alert)
|
|||
tclgetvar("netlist_dir"), get_cell(xctx->sym[i].name, 0), getpid());
|
||||
dbg(1, "vhdl_block_netlist(): split_files: netl_filename=%s\n", netl_filename);
|
||||
fd=fopen(netl_filename, "w");
|
||||
if(!fd) {
|
||||
dbg(0, "vhdl_block_netlist(): unable to write file %s\n", netl_filename);
|
||||
err = 1;
|
||||
goto err;
|
||||
}
|
||||
my_snprintf(cellname, S(cellname), "%s.vhdl", get_cell(xctx->sym[i].name, 0) );
|
||||
}
|
||||
|
||||
|
|
@ -721,6 +726,7 @@ int vhdl_block_netlist(FILE *fd, int i, int alert)
|
|||
set_tcl_netlist_type();
|
||||
if(debug_var==0) xunlink(netl_filename);
|
||||
}
|
||||
err:
|
||||
xctx->netlist_count++;
|
||||
return err;
|
||||
}
|
||||
|
|
|
|||
18
src/xinit.c
18
src/xinit.c
|
|
@ -361,10 +361,10 @@ void init_pixdata()/* populate xctx->fill_type array that is used in create_gc()
|
|||
if(pixdata[i][j]!=0xff) full=0;
|
||||
if(pixdata[i][j]!=0x00) empty=0;
|
||||
}
|
||||
if(full) xctx->fill_type[i] = 1;
|
||||
if(full) xctx->fill_type[i] = 2;
|
||||
else if(empty) xctx->fill_type[i] = 0;
|
||||
else xctx->fill_type[i]=2;
|
||||
if(rainbow_colors && i>5) xctx->fill_type[i]=1; /* 20171212 solid fill style */
|
||||
else xctx->fill_type[i]=1;
|
||||
if(rainbow_colors && i>5) xctx->fill_type[i]=2; /* 20171212 solid fill style */
|
||||
/*fprintf(errfp, "fill_type[%d]= %d\n", i, xctx->fill_type[i]); */
|
||||
}
|
||||
}
|
||||
|
|
@ -434,7 +434,7 @@ void create_gc(void)
|
|||
xctx->gc[i] = XCreateGC(display,xctx->window,0L,NULL);
|
||||
xctx->gcstipple[i] = XCreateGC(display,xctx->window,0L,NULL);
|
||||
XSetStipple(display,xctx->gcstipple[i],pixmap[i]);
|
||||
if(xctx->fill_type[i]==1) XSetFillStyle(display,xctx->gcstipple[i],FillSolid);
|
||||
if(xctx->fill_type[i]==2) XSetFillStyle(display,xctx->gcstipple[i],FillSolid);
|
||||
else XSetFillStyle(display,xctx->gcstipple[i],FillStippled);
|
||||
}
|
||||
}
|
||||
|
|
@ -1177,12 +1177,20 @@ static int source_tcl_file(char *s)
|
|||
if(Tcl_EvalFile(interp, s)==TCL_ERROR) {
|
||||
|
||||
fprintf(errfp, "Tcl_AppInit() error: can not execute %s, please fix:\n", s);
|
||||
fprintf(errfp, "Line No: %d\n", Tcl_GetErrorLine(interp));
|
||||
fprintf(errfp, "%s", tclresult());
|
||||
#if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >=6
|
||||
fprintf(errfp, "Line No: %d\n", Tcl_GetErrorLine(interp));
|
||||
#endif
|
||||
fprintf(errfp, "\n");
|
||||
#if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >=6
|
||||
my_snprintf(tmp, S(tmp), "tk_messageBox -icon error -type ok -message \
|
||||
{Tcl_AppInit() err 1: can not execute %s, please fix:\n%s\nLine No: %d\n}",
|
||||
s, tclresult(), Tcl_GetErrorLine(interp));
|
||||
#else
|
||||
my_snprintf(tmp, S(tmp), "tk_messageBox -icon error -type ok -message \
|
||||
{Tcl_AppInit() err 1: can not execute %s, please fix:\n%s\n}",
|
||||
s, tclresult());
|
||||
#endif
|
||||
if(has_x) {
|
||||
tcleval( "wm withdraw .");
|
||||
tcleval( tmp);
|
||||
|
|
|
|||
|
|
@ -491,7 +491,7 @@ typedef struct
|
|||
unsigned short sel;
|
||||
char *prop_ptr;
|
||||
void *extraptr; /* generic data pointer (images) */
|
||||
short fill;
|
||||
short fill; /* 0: no fill, 1: stippled fill, 2: solid fill */
|
||||
short dash;
|
||||
int ellipse_a, ellipse_b;
|
||||
/* bit0=1 for graph function, bit1=1 for unlocked x axis
|
||||
|
|
@ -1648,6 +1648,7 @@ extern char *my_free(int id, void *ptr);
|
|||
extern size_t my_strcat(int id, char **, const char *);
|
||||
extern size_t my_strcat2(int id, char **, const char *);
|
||||
extern size_t my_mstrcat(int id, char **str, const char *append_str, ...);
|
||||
extern FILE * my_fopen(const char *f, const char *m);
|
||||
extern void *my_memmem(const void *haystack, size_t hlen, const void *needle, size_t nlen);
|
||||
extern char *my_itoa(int i);
|
||||
extern double atof_spice(const char *s);
|
||||
|
|
@ -1764,4 +1765,5 @@ extern const char *create_tmpdir(char *prefix);
|
|||
extern FILE *open_tmpfile(char *prefix, char *suffix, char **filename);
|
||||
extern void create_ps(char** psfile, int what, int fullzoom, int eps);
|
||||
extern void MyXCopyArea(Display* display, Drawable src, Drawable dest, GC gc, int src_x, int src_y, unsigned int width, unsigned int height, int dest_x, int dest_y);
|
||||
extern int win_regexec(const char *options, const char *pattern, const char *name);
|
||||
#endif /*CADGLOBALS */
|
||||
|
|
|
|||
122
src/xschem.tcl
122
src/xschem.tcl
|
|
@ -693,6 +693,72 @@ proc spaces {n {indent 4}} {
|
|||
return [string repeat { } $n]
|
||||
}
|
||||
|
||||
# complex number operators
|
||||
# a + b
|
||||
proc cadd {a b} {
|
||||
lassign $a ra ia
|
||||
lassign $b rb ib
|
||||
set c [list [expr {$ra + $rb}] [expr {$ia + $ib}]]
|
||||
return $c
|
||||
}
|
||||
|
||||
# a - b
|
||||
proc csub {a b} {
|
||||
lassign $a ra ia
|
||||
lassign $b rb ib
|
||||
set c [list [expr {$ra - $rb}] [expr {$ia - $ib}]]
|
||||
return $c
|
||||
}
|
||||
|
||||
# a * b
|
||||
proc cmul {a b} {
|
||||
lassign $a ra ia
|
||||
lassign $b rb ib
|
||||
set c [list [expr {$ra * $rb - $ia * $ib}] [expr {$ra * $ib + $rb * $ia}]]
|
||||
return $c
|
||||
}
|
||||
|
||||
# a / b
|
||||
proc cdiv {a b} {
|
||||
lassign $a ra ia
|
||||
lassign $b rb ib
|
||||
set ra [expr {double($ra)}]
|
||||
set ia [expr {double($ia)}]
|
||||
set rb [expr {double($rb)}]
|
||||
set ib [expr {double($ib)}]
|
||||
set m [expr {$rb * $rb + $ib * $ib}]
|
||||
set c [list [expr {($ra * $rb + $ia * $ib) / $m}] [expr {($rb * $ia - $ra * $ib) / $m}]]
|
||||
return $c
|
||||
}
|
||||
|
||||
# 1/b
|
||||
proc cinv {b} {
|
||||
|
||||
lassign $b rb ib
|
||||
set rb [expr {double($rb)}]
|
||||
set ib [expr {double($ib)}]
|
||||
set m [expr {$rb * $rb + $ib * $ib}]
|
||||
set c [list [expr {$rb / $m}] [expr {-$ib / $m}]]
|
||||
return $c
|
||||
}
|
||||
|
||||
# return real component
|
||||
proc creal {a} {
|
||||
lassign $a ra ia
|
||||
return $ra
|
||||
}
|
||||
|
||||
# return imaginary component
|
||||
proc cimag {a} {
|
||||
lassign $a ra ia
|
||||
return $ia
|
||||
}
|
||||
|
||||
# return resulting impedance of parallel connected impedances a and b
|
||||
proc cparallel {a b} {
|
||||
return [cdiv [cmul $a $b] [cadd $a $b]]
|
||||
}
|
||||
|
||||
# wraps provided table formatted text into a nice looking bordered table
|
||||
# sep is the list of characters used as separators, default are { }, {,}, {\t}
|
||||
# if you want to tabulate data with spaces use only {,} as separator or any other character.
|
||||
|
|
@ -6021,6 +6087,50 @@ proc edit_prop {txtlabel} {
|
|||
return $tctx::rcode
|
||||
}
|
||||
|
||||
# reads metadata tokens from header component of the symbol inside `v {data}` element
|
||||
# and returns dictionary in name of the token as key and value of the token as value in dictionary
|
||||
# Courtesy @georgtree
|
||||
proc symbolParse {file} {
|
||||
try {
|
||||
set file [open $file r]
|
||||
} on error {errmsg erropts} {
|
||||
puts stderr "Error while reading symbol file '$file': $errmsg"
|
||||
return
|
||||
}
|
||||
set data [read $file]
|
||||
close $file
|
||||
# pattern to find v {} and extract content inside brackets
|
||||
set pattern {(?:^|\n)v\s+\{((?:[^{}]|\\[{}])*)\}}
|
||||
if {![regexp $pattern $data -> content]} {
|
||||
return
|
||||
}
|
||||
# outer braces {...} are not part of content, so remove escaping of inner {, } and \ .
|
||||
set content [string map { \\\{ \{ \\\} \} \\\\ \\ } $content]
|
||||
# pattern to find: name="value" or name=value or name = "value" or name = value
|
||||
set pattern {(\w+)\s*=\s*(?:"((?:[^"]|\\["])*)"|(\S+))}
|
||||
set start 0
|
||||
# 'match' variable holds the complete matched pattern, used for searching next one
|
||||
while {[regexp -start $start $pattern $content -> name quotedValue unquotedValue]} {
|
||||
# Determine the value (quoted or unquoted)
|
||||
if {[string length $quotedValue] > 0} {
|
||||
set value $quotedValue
|
||||
# outer quotes are removed from value,
|
||||
# remove escaping of internal backslashes and doublequotes
|
||||
dict append tokens $name [string map {\\\\ \\ \\\" \" } $value]
|
||||
} else {
|
||||
set value $unquotedValue
|
||||
dict append tokens $name $value
|
||||
}
|
||||
# Update the start index to continue searching after this match
|
||||
set start [expr {[string first $value $content $start] + [string length $value]}]
|
||||
# Safety check to prevent infinite loops
|
||||
if {$start <= 0} {
|
||||
break
|
||||
}
|
||||
}
|
||||
return $tokens
|
||||
}
|
||||
|
||||
proc read_data_nonewline {f} {
|
||||
set fid [open $f r]
|
||||
set data [read -nonewline $fid]
|
||||
|
|
@ -6631,8 +6741,12 @@ proc try_download_url {dirname sch_or_sym} {
|
|||
# Example: rel_sym_path /home/schippes/share/xschem/xschem_library/devices/iopin.sym
|
||||
# devices/iopin.sym
|
||||
proc rel_sym_path {symbol} {
|
||||
global OS pathlist
|
||||
global OS pathlist env
|
||||
|
||||
regsub {^~/} $symbol ${env(HOME)}/ symbol
|
||||
if {![regexp {^/} $symbol]} {
|
||||
set symbol [pwd]/$symbol
|
||||
}
|
||||
set curr_dirname [pwd]
|
||||
set name {}
|
||||
foreach path_elem $pathlist {
|
||||
|
|
@ -7768,7 +7882,8 @@ set tctx::global_list {
|
|||
toolbar_visible top_is_subckt transparent_svg undo_type use_lab_wire unselect_partial_sel_wires
|
||||
use_label_prefix use_tclreadline
|
||||
user_wants_copy_cell verilog_2001 verilog_bitblast viewdata_fileid viewdata_filename viewdata_w
|
||||
tctx::vsize xschem_libs xschem_listen_port zoom_full_center
|
||||
tctx::vsize xschem_libs xschem_listen_port zoom_full_center orthogonal_wiring snap_cursor
|
||||
snap_cursor_size cadence_compat use_cursor_for_selection
|
||||
}
|
||||
|
||||
## list of global arrays to save/restore on context switching
|
||||
|
|
@ -8056,7 +8171,7 @@ proc pack_widgets { { topwin {} } } {
|
|||
pack $topwin.statusbar.6 -side left
|
||||
pack $topwin.statusbar.7 -side left
|
||||
pack $topwin.statusbar.10 -side left
|
||||
pack $topwin.statusbar.11 -side left
|
||||
pack $topwin.statusbar.11 -side left
|
||||
pack $topwin.statusbar.9 -side left
|
||||
pack $topwin.statusbar.8 -side left
|
||||
pack $topwin.statusbar.1 -side left -fill x
|
||||
|
|
@ -9228,6 +9343,7 @@ set_ne big_grid_points 0
|
|||
set_ne draw_grid_axes 1
|
||||
set_ne persistent_command 0
|
||||
set_ne intuitive_interface 1
|
||||
set_ne use_cursor_for_selection 0
|
||||
set_ne autotrim_wires 0
|
||||
set_ne cadence_compat 0
|
||||
set_ne infix_interface 1
|
||||
|
|
|
|||
16
src/xschemrc
16
src/xschemrc
|
|
@ -294,6 +294,19 @@
|
|||
#### set cadence_compat; Default: 0 (Cadence-style keybinds are not used by default)
|
||||
# set cadence_compat 1
|
||||
|
||||
#### enable drawing a diamond-shaped cursor at the closest circuit endpoint. Default: disabled (0)
|
||||
# set snap_cursor 1
|
||||
|
||||
#### set snap_cursor_size; Default: 6 (Diamond-shaped cursor that snaps to nearest circuit endpoint)
|
||||
# set snap_cursor_size 6
|
||||
|
||||
#### set cadence_compat; Default: 0 (Cadence-style keybinds are not used by default)
|
||||
# set cadence_compat 1
|
||||
|
||||
#### if set, then, when cursor (regardless of style) is on an object, and user clicks (though mouse pointer is not on the object),
|
||||
#### the object is selected. Default: 0
|
||||
# set use_cursor_for_selection 1
|
||||
|
||||
#### enable to scale grid point size as done with lines at close zoom, default: 0
|
||||
# set big_grid_points 0
|
||||
|
||||
|
|
@ -647,3 +660,6 @@
|
|||
#### Default: not enabled (0)
|
||||
# set fix_mouse_coord 0
|
||||
|
||||
#### redefine some variables to emulate Cadence UI / bindkeys
|
||||
# source /home/schippes/share/xschem/cadence_style_rc
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
v {xschem version=3.4.5 file_version=1.2
|
||||
v {xschem version=3.4.6 file_version=1.2
|
||||
*
|
||||
* This file is part of XSCHEM,
|
||||
* a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit
|
||||
|
|
@ -47,7 +47,7 @@ T {@#0:pinnumber} -10 -27.5 0 1 0.2 0.2 {layer=13}
|
|||
T {@#1:pinnumber} -10 17.5 0 1 0.2 0.2 {layer=13}
|
||||
T {@#0:net_name} 5 -42.5 0 0 0.15 0.15 {layer=15 hide=instance}
|
||||
T {@#1:net_name} 5 32.5 0 0 0.15 0.15 {layer=15 hide=instance}
|
||||
T {@name} 15 -18.75 0 0 0.2 0.2 {}
|
||||
T {@value} 15 -3.75 0 0 0.2 0.2 {}
|
||||
T {m=@m} 15 11.25 0 0 0.2 0.2 {}
|
||||
T {@spice_get_current} -12.5 5 0 1 0.2 0.2 {layer=17}
|
||||
T {@name} 15 -18.75 0 0 0.2 0.2 {}
|
||||
T {@value} 15 -6.25 0 0 0.2 0.2 {}
|
||||
T {m=@m} 15 6.25 0 0 0.2 0.2 {}
|
||||
|
|
|
|||
|
|
@ -21,21 +21,21 @@ v {xschem version=3.4.6 file_version=1.2
|
|||
}
|
||||
G {}
|
||||
K {type=opamp_va
|
||||
format="@name @@OUT @@IN1 @@IN2 @model"
|
||||
format="@name @@OUT @@IN1 @@IN2 @model gain=@gain amplitude=@amplitude offset=@offset"
|
||||
|
||||
template="name=X1 model=diff_amp_cell"
|
||||
template="name=X1 model=diff_amp_cell gain=40 amplitude=3 offset=1.5"
|
||||
|
||||
device_model="tcleval(
|
||||
.subckt diff_amp_cell OUT IN1 IN2
|
||||
N1 out in1 in2 diff_amp_model
|
||||
.ends diff_amp_cell
|
||||
|
||||
.model diff_amp_model diff_amp
|
||||
|
||||
.control
|
||||
* following line specifies the location for the .osdi file so ngspice can use it.
|
||||
pre_osdi $USER_CONF_DIR/xschem_library/diff_amp.osdi
|
||||
.endc
|
||||
|
||||
.model diff_amp_model diff_amp $ gain=40 amplitude=3 offset=1.5
|
||||
|
||||
.subckt diff_amp_cell OUT IN1 IN2 gain=40 amplitude=3 offset=1.5
|
||||
N1 out in1 in2 diff_amp_model gain=gain amplitude=amplitude offset=offset
|
||||
.ends diff_amp_cell
|
||||
)"
|
||||
}
|
||||
V {}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ V {}
|
|||
S {}
|
||||
E {}
|
||||
B 2 840 -580 1640 -170 {flags=graph
|
||||
y1=0
|
||||
y2=6
|
||||
y1=6.3e-14
|
||||
y2=5
|
||||
ypos1=0
|
||||
ypos2=2
|
||||
divy=5
|
||||
|
|
@ -49,7 +49,7 @@ logy=0
|
|||
}
|
||||
B 2 840 -990 1640 -580 {flags=graph
|
||||
y1=0
|
||||
y2=40
|
||||
y2=100
|
||||
ypos1=0
|
||||
ypos2=2
|
||||
divy=5
|
||||
|
|
@ -68,10 +68,9 @@ unitx=1
|
|||
logx=0
|
||||
logy=0
|
||||
}
|
||||
P 4 5 140 -600 140 -880 710 -880 710 -600 140 -600 {}
|
||||
P 4 5 30 -600 30 -880 740 -880 740 -600 30 -600 {}
|
||||
P 4 7 410 -600 410 -560 420 -560 410 -540 400 -560 410 -560 410 -600 {}
|
||||
T {// importing libs
|
||||
|
||||
`include "discipline.h"
|
||||
|
||||
module diff_amp(
|
||||
|
|
@ -79,17 +78,17 @@ module diff_amp(
|
|||
input electrical in1,
|
||||
input electrical in2);
|
||||
|
||||
parameter real gain = 40; // setting gain to 40 of the differential amplifier
|
||||
parameter real vcc = 3; // swing from -vcc/2 to +vcc/2
|
||||
parameter real offset = 3;// added offset
|
||||
(* desc="gain", units="", type="instance" *) parameter real gain = 40 from [-inf: inf];
|
||||
(* desc="amplitude", units="", type="instance" *) parameter real amplitude = 3 from [-inf: inf];
|
||||
(* desc="offset", units="", type="instance" *) parameter real offset = 1.5 from [-inf: inf];
|
||||
|
||||
analog begin
|
||||
|
||||
V(out) <+ offset / 2 + vcc / 2 * tanh( gain / vcc * 2 * V(in1, in2));
|
||||
V(out) <+ offset + amplitude / 2 * tanh( gain / amplitude * 2 * V(in1, in2));
|
||||
|
||||
end
|
||||
endmodule
|
||||
} 150 -870 0 0 0.2 0.2 {font=monospace}
|
||||
} 40 -870 0 0 0.2 0.2 {font=monospace}
|
||||
T {create a diff_amp.va file with following code
|
||||
and compile it into a .osdi file with openvaf.} 190 -940 0 0 0.4 0.4 {}
|
||||
N 180 -450 320 -450 {lab=B}
|
||||
|
|
@ -100,7 +99,6 @@ N 180 -330 180 -290 {lab=0}
|
|||
N 80 -330 80 -290 {lab=0}
|
||||
N 80 -530 80 -390 {lab=A}
|
||||
N 180 -450 180 -390 {lab=B}
|
||||
C {diff_amp.sym} 420 -490 0 0 {name=X1}
|
||||
C {lab_pin.sym} 640 -490 0 1 {name=p1 sig_type=std_logic lab=Z}
|
||||
C {lab_pin.sym} 80 -530 0 0 {name=p2 sig_type=std_logic lab=A}
|
||||
C {lab_pin.sym} 180 -450 0 0 {name=p3 sig_type=std_logic lab=B}
|
||||
|
|
@ -118,7 +116,7 @@ C {code_shown.sym} 240 -320 0 0 {name=COMMANDS only_toplevel=false value="
|
|||
set appendwrite
|
||||
remzerovec
|
||||
write tb_diff_amp.raw
|
||||
quit 0
|
||||
* quit 0
|
||||
.endc
|
||||
"}
|
||||
C {launcher.sym} 670 -120 0 0 {name=h5
|
||||
|
|
@ -130,3 +128,4 @@ C {launcher.sym} 670 -170 0 0 {name=h1
|
|||
descr="OP annotate"
|
||||
tclcommand="xschem annotate_op"
|
||||
}
|
||||
C {diff_amp.sym} 420 -490 0 0 {name=X1 model=diff_amp_cell gain=100 amplitude=5 offset=2.5}
|
||||
|
|
|
|||
Loading…
Reference in New Issue