diff --git a/.clang-format b/.clang-format deleted file mode 100644 index 553942d86..000000000 --- a/.clang-format +++ /dev/null @@ -1,107 +0,0 @@ -# Initially made using -# clang-format -style=llvm -dump-config > .clang-format -# Then lines were modified to get the desired results -# -# Incorporate these options by adding the flag -style=file -# and putting this file in the directory of the file being formatted or -# one of its parent directories -# -# See http://clang.llvm.org/docs/ClangFormat.html for usage and -# http://clang.llvm.org/docs/ClangFormatStyleOptions.html for options -# ---- -Language: Cpp -# BasedOnStyle: LLVM -AccessModifierOffset: 0 -AlignAfterOpenBracket: DontAlign -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignEscapedNewlinesLeft: false -AlignOperands: false -AlignTrailingComments: false -AllowAllParametersOfDeclarationOnNextLine: false -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: None -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: false -BinPackArguments: true -BinPackParameters: true -BreakBeforeBraces: Custom -BraceWrapping: - AfterClass: false - AfterControlStatement: false - AfterEnum: false - AfterFunction: true - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false - BeforeCatch: false - BeforeElse: true - IndentBraces: false -BreakAfterJavaFieldAnnotations: false -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Custom -BreakBeforeTernaryOperators: false -BreakConstructorInitializersBeforeComma: false -BreakStringLiterals: true -ColumnLimit: 78 -CommentPragmas: '^ IWYU pragma:' # not sure what this should be -ConstructorInitializerAllOnOneLineOrOnePerLine: false -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 8 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] -IncludeCategories: # need to consider more - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - - Regex: '^(<|"(gtest|isl|json)/)' - Priority: 3 - - Regex: '.*' - Priority: 1 -IncludeIsMainRegex: '$' -IndentCaseLabels: true -IndentWidth: 4 -IndentWrappedFunctionNames: false -JavaScriptQuotes: Leave -JavaScriptWrapImports: true -KeepEmptyLinesAtTheStartOfBlocks: true -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 4 -NamespaceIndentation: None -ObjCBlockIndentWidth: 2 # Not applicable (N/A) -ObjCSpaceAfterProperty: false # N/A -ObjCSpaceBeforeProtocolList: true # N/A -PenaltyBreakBeforeFirstCallParameter: 19 # 19 was the original value -PenaltyBreakComment: 300 # 300 was the original value -PenaltyBreakFirstLessLess: 120 # 120 was the original value -PenaltyBreakString: 1000 # 1000 was the original value -PenaltyExcessCharacter: 10000000 # 1000000 was the original value -PenaltyReturnTypeOnItsOwnLine: 60 # 60 was the original value -PointerAlignment: Right -ReflowComments: true -SortIncludes: true -SpaceAfterCStyleCast: true -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInContainerLiterals: true # N/A -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Cpp11 -TabWidth: 8 # N/A since not using tabs -UseTab: Never -# ... generated by the command here. Not sure why - diff --git a/README.utf8 b/README.utf8 new file mode 100644 index 000000000..92472e34e --- /dev/null +++ b/README.utf8 @@ -0,0 +1,35 @@ +use utf-8 for encoding of strings, this enables UNICODE +international characters sets (of nearly any language) +in plot titles and labels, file and folder names. + +Windows uses utf-16 and conversion functions between utf-8 +and utf-16, if access to Windows API functions is needed. +A special fopen has been defined. + +In addition, plot labels on the y axis now are placed +vertically, 90°, by using the Windows API or the Linux Xft library. + +Postscript plotting uses only a UNICODE subset, namely +ISO-8859-1/ISO-8859-15, that allows extended ascii. + +Better looking fonts are now used for labelling the axes. + +Variables xbrushwidth and xgridwidth (to be set e.g. in +.spiceinit or directly before a plot command) allow setting +separately the linewidths of the graph (xbrushwidth) and +the grid (xgridwidth). + +Slight modification of the Windows GUI string window to +enhance readability. + +Windows GUI is now more responsive during lengthy op +calculations. + +UNICODE in Gnuplot and (limited) in Postscript are supported. +You will need to download and install gnuplot and a PS viewer +(e.g. ghostscript, gv or others). + +Input files to ngspice now have to be utf-8 encoded. ANSI +encoded files will fail (Notepad++ on Windows allows a simple +conversion). For an ANSI version of ngspice you have to +compile it with the configure flag --disable-utf8. diff --git a/configure.ac b/configure.ac index c969c1603..9aaf51cc2 100644 --- a/configure.ac +++ b/configure.ac @@ -91,6 +91,10 @@ AC_ARG_WITH([tcl], AC_ARG_WITH([ngshared], [AS_HELP_STRING([--with-ngshared], [Compiles ngspice as shared library (dll)])]) +# --disable-utf8: don't use utf-8 and tchar for string representation, UNICODE support disabled +AC_ARG_ENABLE([utf8], + [AS_HELP_STRING([--disable-utf8], [Don't use utf-8 or tchar (default is UNICODE support with utf-8)])]) + # old options, not maintained, may even not work at all # --enable-ansi: try to force --ansi option to the compiler @@ -296,6 +300,35 @@ else dprefix=$prefix fi +#### +### check for operating system at compile time +case $host_os in + *mingw* | *msys* ) + AC_DEFINE([OS_COMPILED], [1], [MINGW for MS Windows]) + ;; + *cygwin* ) + AC_DEFINE([OS_COMPILED], [2], [Cygwin for MS Windows]) + ;; + *freebsd* ) + AC_DEFINE([OS_COMPILED], [3], [FreeBSD]) + ;; + *openbsd* ) + AC_DEFINE([OS_COMPILED], [4], [OpenBSD]) + ;; + *solaris* ) + AC_DEFINE([OS_COMPILED], [5], [Solaris]) + ;; + *linux* ) + AC_DEFINE([OS_COMPILED], [6], [Linux]) + ;; + *darwin* ) + AC_DEFINE([OS_COMPILED], [7], [macOS]) + ;; + * ) + AC_DEFINE([OS_COMPILED], [0], [Other Operating System]) + ;; +esac + ########################################################################## # # ngspice as shared library (ngspice.so or ngspice.dll) @@ -668,18 +701,13 @@ fi # Checks for X libraries - if X11 wasn't found then don't make following # tests and compile without X11 support - otherwise, check if the following # libraries are present (error if they are not) -# In CYGWIN library ordering has to be changed. Is this compatible to LINUX? # XShmAttach is a struct in CYGWIN, not a function -# SJB: 13th march 2005 -# Library order is giving linker warnings on MacOSX -# It's not clear to me which order is required for Cygwin (see comment above) -# and neither can I find any authoritative answer for the correct link order -# for MacOSX or Linux, but -# -lXaw -lXmu -lXt -lXext -lX11 -# seems to be the popular choice. -# (The previous order was -lX11 -lXt -lXext -lXmu -lXaw) +# Library order is +# -lXaw -lXmu -lXt -lXext -lX11 (-lXft -lfontconfig -lXrender -lfreetype) +# Xft is optional, allows text rotation in plots if test "x$no_x" != xyes ; then + X_CFLAGS="$X_CFLAGS -I/usr/include/freetype2" AC_CHECK_LIB([Xaw], [main], [X_LIBS="$X_LIBS -lXaw"], [AC_MSG_ERROR([Couldn't find Xaw library])], [$X_LIBS $X_EXTRA_LIBS]) AC_CHECK_LIB([Xmu], [main], [X_LIBS="$X_LIBS -lXmu"], @@ -688,6 +716,21 @@ if test "x$no_x" != xyes ; then AC_CHECK_LIB([Xext], [XShmAttach], [X_LIBS="$X_LIBS -lXext"], [AC_MSG_ERROR([Couldn't find Xext library])], [$X_LIBS $X_EXTRA_LIBS]) X_LIBS="$X_LIBS -lX11" + AC_CHECK_LIB([Xft], [main], + [AC_DEFINE([HAVE_LIBXFT], [1], [Have xft routines in libxft])] + X_LIBS="$X_LIBS -lXft -lfontconfig -lXrender -lfreetype" + has_xft=yes, + [has_xft=no], [$X_LIBS $X_EXTRA_LIBS]) + + if test "x$has_xft" = xyes ; then + AC_CHECK_LIB([fontconfig], [main], [], + [AC_MSG_ERROR([Couldn't find fontconfig library])], [$X_LIBS $X_EXTRA_LIBS]) +# AC_CHECK_LIB([Xrender], [main], [], +# [AC_MSG_ERROR([Couldn't find Xrender library])], [$X_LIBS $X_EXTRA_LIBS]) + AC_CHECK_LIB([freetype], [main], [], + [AC_MSG_ERROR([Couldn't find freetype library])], [$X_LIBS $X_EXTRA_LIBS]) + fi + has_no_x=false else AC_DEFINE([X_DISPLAY_MISSING]) @@ -714,7 +757,7 @@ if test "x$enable_oldapps" = xyes ; then AC_MSG_RESULT([ngnutmeg ngsconvert ngproc2mod ngmultidec ngmakeidx nghelp are made.]) else AC_MSG_RESULT([ngnutmeg ngsconvert ngproc2mod ngmultidec ngmakeidx nghelp are not made.]) - AC_MSG_RESULT([No internal help available.]) + AC_MSG_RESULT([No internal help available.]) AC_DEFINE([NOINTHELP], [1], [Internal (old) help not available]) fi AM_CONDITIONAL([OLDAPPS], [test "x$enable_oldapps" = xyes]) @@ -932,6 +975,10 @@ if test "x$enable_smltmsdebug" = xyes; then AC_DEFINE([D_DBG_SMALLTIMES], [], [Define if we want debug distortion analysis (SMALLTIMES)]) AC_MSG_RESULT([WARNING: Distortion analysis debug *D_DBG_SMALLTIMES* is enabled]) fi +if test "x$enable_utf8" = xno; then + AC_DEFINE([EXT_ASC], [], [Define if you want to disable UNICODE support]) + AC_MSG_RESULT([WARNING: UNICOPDE support is disabled, extended ascii is enabled instead]) +fi AC_PROG_YACC AC_PATH_PROG([BISON], [bison]) diff --git a/examples/memristor/memristor.sp b/examples/memristor/memristor.sp index fdb9488a7..0664f1075 100644 --- a/examples/memristor/memristor.sp +++ b/examples/memristor/memristor.sp @@ -57,9 +57,9 @@ plot tran1.alli tran2.alli alli title 'Memristor with threshold: Internal Progra settype impedance xmem.x1 tran1.xmem.x1 tran2.xmem.x1 plot xmem.x1 tran1.xmem.x1 tran2.xmem.x1 title 'Memristor with threshold: resistance' * resistance versus voltage (change occurs only above threshold!) -plot xmem.x1 vs v(1) tran1.xmem.x1 vs tran1.v(1) tran2.xmem.x1 vs tran2.v(1) title 'Memristor with threshold: resistance' +plot xmem.x1 vs v(1) tran1.xmem.x1 vs tran1.v(1) tran2.xmem.x1 vs tran2.v(1) retraceplot title 'Memristor with threshold: resistance' * current through resistor for all plots versus voltage -plot i(v1) vs v(1) tran1.i(v1) vs tran1.v(1) tran2.i(v1) vs tran2.v(1) title 'Memristor with threshold: external current loops' +plot i(v1) vs v(1) tran1.i(v1) vs tran1.v(1) tran2.i(v1) vs tran2.v(1) retraceplot title 'Memristor with threshold: external current loops' .endc .end diff --git a/examples/memristor/memristor_x.sp b/examples/memristor/memristor_x.sp index 1c283e734..98fbc6528 100644 --- a/examples/memristor/memristor_x.sp +++ b/examples/memristor/memristor_x.sp @@ -47,11 +47,11 @@ Rmem plus minus r={V(x)} op print all ac lin 101 1 100k -plot v(11) +*plot v(11) * approx. 100 simulation points let deltime = stime/100 tran $&deltime $&stime uic -* plot i(v1) vs v(1) +*plot i(v1) vs v(1) retrace *** you may just stop here *** * raise the frequency let newfreq = 1.2/stime @@ -75,9 +75,9 @@ let res2 = tran2.v(1)/(tran2.I(v1) + 1e-16) settype impedance res res1 res2 plot res vs time res1 vs tran1.time res2 vs tran2.time title 'Memristor with threshold: resistance' * resistance versus voltage (change occurs only above threshold!) -plot res vs v(1) res1 vs tran1.v(1) res2 vs tran2.v(1) title 'Memristor with threshold: resistance' +plot res vs v(1) res1 vs tran1.v(1) res2 vs tran2.v(1) retraceplot title 'Memristor with threshold: resistance' * current through resistor for all plots versus voltage -plot i(v1) vs v(1) tran1.i(v1) vs tran1.v(1) tran2.i(v1) vs tran2.v(1) title 'Memristor with threshold: external current loops' +plot i(v1) vs v(1) tran1.i(v1) vs tran1.v(1) tran2.i(v1) vs tran2.v(1) retraceplot title 'Memristor with threshold: external current loops' .endc .end diff --git a/examples/utf-8/стекло/ext-ascii-1.cir b/examples/utf-8/стекло/ext-ascii-1.cir new file mode 100644 index 000000000..146f874ce --- /dev/null +++ b/examples/utf-8/стекло/ext-ascii-1.cir @@ -0,0 +1,30 @@ +* test de titre +* file is encoded as ASCII ! +* will lead to error in the ngspice UNICODE utf8 version +* is o.k. only if ngspice is compiled with --disable-utf8 flag + +.control + +set hcopydevtype = postscript +set hcopypscolor=1 +set color2=rgb:F/0/0 + +let x = vector(5) +let y = exp(x) + +plot y vs x xlabel 'Mon x' ylabel 'Mon y' +hardcopy plot_1.ps y vs x xlabel 'Mon X' ylabel 'Mon Y' + +plot y vs x xlabel 'Mon x' title 'Mon titre' +hardcopy plot_2.ps y vs x xlabel 'Mon x' title 'Mon titre' + +plot y vs x xlabel test +hardcopy plot_3.ps y vs x xlabel test + +plot y vs x +hardcopy plot_4.ps y vs x + +plot y vs x xlabel 'Labellis X' ylabel 'Labellise Y' title 'Titr' +hardcopy plot_5.ps y vs x xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' + +.endc diff --git a/examples/utf-8/стекло/ext-ascii-2.cir b/examples/utf-8/стекло/ext-ascii-2.cir new file mode 100644 index 000000000..ddeee64b0 --- /dev/null +++ b/examples/utf-8/стекло/ext-ascii-2.cir @@ -0,0 +1,28 @@ +* test de titr +* file is encoded as ASCII ! +* will lead to error in the ngspice UNICODE utf8 version +* is o.k. only if ngspice is compiled with --disable-utf8 flag + +.control +set encoding=extended_ascii +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +setcs hcopyfont="Garamond" +set hcopyfontsize=14 + +let x = vector(5) +let y = exp(x) +setcs wfont="Garamond Fett" +set wfont_size=16 +plot y vs x xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' +plot y vs x xlabel 'Labellis X' title 'Titr' +plot y vs x+0.001 xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' loglog +plot y vs x+0.001 xlabel 'Labellis X' title 'Titr' loglog + +hardcopy plot_5.ps y vs x xlabel 'Labellis X' ylabel 'Labellis Y' title 'Titr' +shell Start /B plot_5.ps +write D:\Spice_general\tests\ext_unic_test.raw y x +*quit +.endc diff --git a/examples/utf-8/стекло/ext-utf8-2.cir b/examples/utf-8/стекло/ext-utf8-2.cir new file mode 100644 index 000000000..194e77fe0 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-2.cir @@ -0,0 +1,60 @@ +* test de titré +.control +set hcopydevtype = postscript +set hcopypscolor=18 +set hcopypstxcolor=21 +set hcopyscale=1 +set color2=rgb:FF/0/0 +setcs hcopyfont=Arial +set hcopyfontsize=18 + +let x = vector(5) +let y = exp(x) +setcs wfont=Arial +set wfont_size=18 +setcs xfont='Noto Sans Chinese' +*set xfont_size=18 + +set xgridwidth=4 +set xbrushwidth=1 + +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +set xgridwidth=1 +set xbrushwidth=4 + +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +*plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' + +if ($oscompiled = 1) or ($oscompiled = 8) + shell Start /B plot_5.ps +endif +if ($oscompiled = 2) + shell xterm -e gs plot_5.ps & +endif +if ($oscompiled = 6) + shell gv plot_5.ps & +endif +if ($oscompiled = 7) + shell open -a Preview plot_5.ps & +endif + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc diff --git a/examples/utf-8/стекло/ext-utf8-3.cir b/examples/utf-8/стекло/ext-utf8-3.cir new file mode 100644 index 000000000..4fe53fc3b --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-3.cir @@ -0,0 +1,66 @@ +* test de titré +* set oscompiled nn [0..8] +* nn: Other MINGW Cygwin FreeBSD OpenBSD Solaris Linux macOS Visual_Studio +* all text snippets (nonsense text) from http://kermitproject.org/utf8.html + +.control +set hcopydevtype = postscript +set hcopypscolor=25 +set hcopypstxcolor=21 +set hcopyscale=1 +if $oscompiled = 8 + set color2=rgb:FF/0/0 +else + set color2=rgb:F/0/0 +endif +setcs hcopyfont=Arial +set hcopyfontsize=18 + +let x = vector(5) +let y = exp(x) +setcs wfont=Arial +set wfont_size=18 +setcs xfont='Noto Sans' +*set xfont_size=18 + +set xgridwidth=4 +set xbrushwidth=1 + +*hardcopy + +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +if $oscompiled = 6 + shell export LC_CTYPE ="de_DE.UTF-8" +endif +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +set xgridwidth=1 +set xbrushwidth=4 + +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +if $oscompiled = 6 + shell export LC_CTYPE ="de_DE.UTF-8" +endif +gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +if $oscompiled = 8 or $oscompiled = 1 + shell Start /B plot_5.ps +else + shell gv plot_5.ps & +endif + +*wrdata test.out y vs x +*asciiplot atest.out y vs x + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc diff --git a/examples/utf-8/стекло/ext-utf8-c.cir b/examples/utf-8/стекло/ext-utf8-c.cir new file mode 100644 index 000000000..a4b336463 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-c.cir @@ -0,0 +1,58 @@ +titré 'test of various color inputs for background, text/grid and graphs 1' +.control +set hcopydevtype = postscript +set hcopypscolor=25 +set hcopypstxcolor=21 +set hcopyscale=1 +*set color2=rgb:F/0/0 + +setcs hcopyfont=Arial +set hcopyfontsize=18 + + +let x = vector(5) +let y = exp(x) +setcs wfont=Arial +set wfont_size=18 +setcs xfont='Noto Sans' +*set xfont_size=18 + +set xgridwidth=4 +set xbrushwidth=1 +set color0=white +set color2=brown +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +set color0=black +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +set color0=Blue +set color1=Yellow +set color2=Lime +set xgridwidth=1 +set xbrushwidth=4 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +unset color1 +set color0=MediumBlue +set color2=Magenta +plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +set color0=GreenYellow +set color2=Magenta +plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +set color0=black +set color2=pink +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +*gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +*shell Start /B plot_5.ps +*shell gv plot_5.ps & + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc diff --git a/examples/utf-8/стекло/ext-utf8-c2.cir b/examples/utf-8/стекло/ext-utf8-c2.cir new file mode 100644 index 000000000..d1ae08e3b --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-c2.cir @@ -0,0 +1,59 @@ +* titré 'test of various color inputs for background, text/grid and graphs 2' +.control +set hcopydevtype = postscript +set hcopypscolor=25 +set hcopypstxcolor=21 +set hcopyscale=1 +*set color2=rgb:F/0/0 + +setcs hcopyfont=Arial +set hcopyfontsize=18 + + +let x = vector(5) +let y = exp(x) +setcs wfont=Arial +set wfont_size=18 +setcs xfont='Noto Sans' +*set xfont_size=18 + +set xgridwidth=4 +set xbrushwidth=1 +set color0=white +*set color2=brown +set color2=rgbd:255/0/0 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +set color0=black +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +set color0=Blue +set color1=Yellow +set color2=rgb:00/FF/00 +set xgridwidth=1 +set xbrushwidth=4 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +unset color1 +set color0=MediumBlue +set color2=Magenta +plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +set color0=GreenYellow +set color2=rgbd:128/128/75 +plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +set color0=black +set color2=pink +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +*gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +*shell Start /B plot_5.ps +*shell gv plot_5.ps & + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc diff --git a/examples/utf-8/стекло/ext-utf8-c4.cir b/examples/utf-8/стекло/ext-utf8-c4.cir new file mode 100644 index 000000000..8543156dd --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-c4.cir @@ -0,0 +1,33 @@ +* titré 'test of various color inputs for background, text/grid and graphs 4' +* to figure out the available font names, run the command +* 'fc-list | cut -f2 -d: | sort -u | less -r > fonts-avail.txt' +.control + +let x = vector(5) +let y = exp(x) + +*setcs xfont='Baekmuk Dotum' +setcs xfont='Noto Sans CJK JP' +*setcs xfont='맑은 고딕' +set xfont_size=20 + +set xgridwidth=1 +set xbrushwidth=8 +set color2=rgbd:0/126/0 +set color0=blue +unset nolegend +* color1 (text/grid) selected automatically +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +set color2=rgbd:0/0/255 +set color1=rgb:0/0/0 +set color0=white +set xbrushwidth=4 +set xgridwidth=2 +set nolegend +plot y vs x xlabel '나는 유리를 먹을 수 있어요' ylabel 'それは私を傷つけません' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc diff --git a/examples/utf-8/стекло/ext-utf8-cyg2.cir b/examples/utf-8/стекло/ext-utf8-cyg2.cir new file mode 100644 index 000000000..4f48b7e30 --- /dev/null +++ b/examples/utf-8/стекло/ext-utf8-cyg2.cir @@ -0,0 +1,42 @@ +* test de titré + +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +setcs hcopyfont=Arial +set hcopyfontsize=14 +set color0="black" +set color1="white" +let x = vector(5) +let y = exp(x) +setcs xfont="Times New Roman" +set xfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +set color0="white" +set color1="black" +set xfont_size=16 +setcs xfont="Arial" +plot y vs x xlabel 'Я могу есть стекло, оно мне не вредит' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Я могу есть стекло, оно мне не вредит' +set color0="yellow" +set color1="red" +set xfont_size=18 +setcs xfont="Noto Sans CJK JP Medium" +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog + +*plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog + +*hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +*shell Start /B plot_5.ps +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体。 + +setcs sourcepath = ( "D:/Spice_general/tests/utf-8/стекло/있어요" ) +source ext-utf8-2.cir + +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/os_compiled.sp b/examples/utf-8/стекло/os_compiled.sp new file mode 100644 index 000000000..dec8ddcfa --- /dev/null +++ b/examples/utf-8/стекло/os_compiled.sp @@ -0,0 +1,34 @@ +*ng_script test for oscompiled + +.control +if $oscompiled = 0 + echo [0], Other +endif +if $oscompiled = 1 + echo [1], MINGW for MS Windows +endif +if $oscompiled = 2 + echo [2], Cygwin for MS Windows +endif +if $oscompiled = 3 + echo [3], FreeBSD +endif +if $oscompiled = 4 + echo [4], OpenBSD +endif +if $oscompiled = 5 + echo [5], Solaris +endif +if $oscompiled = 6 + echo [6], Linux +endif +if $oscompiled = 7 + echo [7], macOS +endif +if $oscompiled = 8 + echo [8], Visual Studio for MS Windows +endif + +.endc + +.end diff --git a/examples/utf-8/стекло/있어요/adder_mos.cir b/examples/utf-8/стекло/있어요/adder_mos.cir new file mode 100644 index 000000000..3f0e7af7c --- /dev/null +++ b/examples/utf-8/стекло/있어요/adder_mos.cir @@ -0,0 +1,82 @@ + 유리를 - 4 BIT ALL-NAND-GATE BINARY ADDER + +*** SUBCIRCUIT DEFINITIONS +.SUBCKT NAND in1 in2 out VDD +* NODES: INPUT(2), OUTPUT, VCC +M1 out in2 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M2 net.1 in2 0 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p +M3 out in1 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M4 out in1 net.1 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p +.ENDS NAND + +.SUBCKT ONEBIT 1 2 3 4 5 6 +* NODES: INPUT(2), CARRY-IN, OUTPUT, CARRY-OUT, VCC +X1 1 2 7 6 NAND +X2 1 7 8 6 NAND +X3 2 7 9 6 NAND +X4 8 9 10 6 NAND +X5 3 10 11 6 NAND +X6 3 11 12 6 NAND +X7 10 11 13 6 NAND +X8 12 13 4 6 NAND +X9 11 7 5 6 NAND +.ENDS ONEBIT + +.SUBCKT TWOBIT 1 2 3 4 5 6 7 8 9 +* NODES: INPUT - BIT0(2) / BIT1(2), OUTPUT - BIT0 / BIT1, +* CARRY-IN, CARRY-OUT, VCC +X1 1 2 7 5 10 9 ONEBIT +X2 3 4 10 6 8 9 ONEBIT +.ENDS TWOBIT + +.SUBCKT FOURBIT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +* NODES: INPUT - BIT0(2) / BIT1(2) / BIT2(2) / BIT3(2), +* OUTPUT - BIT0 / BIT1 / BIT2 / BIT3, CARRY-IN, CARRY-OUT, VCC +X1 1 2 3 4 9 10 13 16 15 TWOBIT +X2 5 6 7 8 11 12 16 14 15 TWOBIT +.ENDS FOURBIT + +*** POWER +VCC 99 0 DC 3.3V + +*** ALL INPUTS +VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS) +VIN1B 2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) +VIN2A 3 0 DC 0 PULSE(0 3 0 5NS 5NS 50NS 200NS) +VIN2B 4 0 DC 0 PULSE(0 3 0 5NS 5NS 90NS 400NS) +VIN3A 5 0 DC 0 PULSE(0 3 0 5NS 5NS 170NS 800NS) +VIN3B 6 0 DC 0 PULSE(0 3 0 5NS 5NS 330NS 1600NS) +VIN4A 7 0 DC 0 PULSE(0 3 0 5NS 5NS 650NS 3200NS) +VIN4B 8 0 DC 0 PULSE(0 3 0 5NS 5NS 1290NS 6400NS) + +*** DEFINE NOMINAL CIRCUIT +X1 1 2 3 4 5 6 7 8 9 10 11 12 0 13 99 FOURBIT + +.option noinit acct +.TRAN 500p 640NS +* save inputs +.save V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) + +* use BSIM3 model with default parameters +.model n1 nmos level=49 version=3.3.0 +.model p1 pmos level=49 version=3.3.0 +*.include ./Modelcards/modelcard32.nmos +*.include ./Modelcards/modelcard32.pmos + +.control +if $?batchmode +else +pre_set strict_errorhandling +unset ngdebug +*save outputs and specials +save x1.x1.x1.7 V(9) V(10) V(11) V(12) V(13) +run +display +* plot the inputs, use offset to plot on top of each other +plot v(1) v(2)+4 v(3)+8 v(4)+12 v(5)+16 v(6)+20 v(7)+24 v(8)+28 +* plot the outputs, use offset to plot on top of each other +plot v(9) v(10)+4 v(11)+8 v(12)+12 v(13)+16 +endif +.endc + +.END diff --git a/examples/utf-8/стекло/있어요/adder_mos3.cir b/examples/utf-8/стекло/있어요/adder_mos3.cir new file mode 100644 index 000000000..ed90d0d58 --- /dev/null +++ b/examples/utf-8/стекло/있어요/adder_mos3.cir @@ -0,0 +1,85 @@ + 4 BIT ALL-NAND-GATE BINARY ADDER with node names 能 and せん + +*** SUBCIRCUIT DEFINITIONS +.SUBCKT NAND in1 in2 out VDD +* NODES: INPUT(2), OUTPUT, VCC +M1 out in2 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M2 net.1 in2 0 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p +M3 out in1 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M4 out in1 net.1 0 n1 W=3u L=0.35u pd=9u ad=9p ps=9u as=9p +.ENDS NAND + +.SUBCKT ONEдBIT 能 2 せん 4 5 6 +* NODES: INPUT(2), CARRY-IN, OUTPUT, CARRY-OUT, VCC +X1 能 2 7 6 NAND +X2 能 7 8 6 NAND +X나는 2 7 9 6 NAND +X4 8 9 10 6 NAND +X5 せん 10 11 6 NAND +X6 せん 11 12 6 NAND +X7 10 11 13 6 NAND +XЯ8 12 13 4 6 NAND +XЯ9 11 7 5 6 NAND +.ENDS ONEдBIT + +.SUBCKT TWOBIT 1 2 3 4 5 6 7 8 9 +* NODES: INPUT - BIT0(2) / BIT1(2), OUTPUT - BIT0 / BIT1, +* CARRY-IN, CARRY-OUT, VCC +X1 1 2 7 5 10 9 ONEдBIT +X2 3 4 10 6 8 9 ONEдBIT +.ENDS TWOBIT + +.SUBCKT FOURBIT 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +* NODES: INPUT - BIT0(2) / BIT1(2) / BIT2(2) / BIT3(2), +* OUTPUT - BIT0 / BIT1 / BIT2 / BIT3, CARRY-IN, CARRY-OUT, VCC +X1 1 2 3 4 9 10 13 16 15 TWOBIT +X2 5 6 7 8 11 12 16 14 15 TWOBIT +.ENDS FOURBIT + +*** POWER +V을을 99 0 DC 3.3V + +*** ALL INPUTS +VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS) +VIN1B 2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) +VIN2A 3 0 DC 0 PULSE(0 3 0 5NS 5NS 50NS 200NS) +VIN2B 4 0 DC 0 PULSE(0 3 0 5NS 5NS 90NS 400NS) +VIN3A 5 0 DC 0 PULSE(0 3 0 5NS 5NS 170NS 800NS) +VIN3B 6 0 DC 0 PULSE(0 3 0 5NS 5NS 330NS 1600NS) +VIN4A 7 0 DC 0 PULSE(0 3 0 5NS 5NS 650NS 3200NS) +VIN4B 8 0 DC 0 PULSE(0 3 0 5NS 5NS 1290NS 6400NS) + +*** DEFINE NOMINAL CIRCUIT +X1 1 2 3 4 5 6 7 8 9 10 11 身12 0 Я13 99 FOURBIT + +.option noinit acct +.TRAN 500p 6400NS +* save inputs +.save V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) + +* use BSIM3 model with default parameters +.model n1 nmos level=49 version=3.3.0 +.model p1 pmos level=49 version=3.3.0 +*.include ./Modelcards/modelcard32.nmos +*.include ./Modelcards/modelcard32.pmos + +.control +* for CYGWIN +setcs xfont='Noto Sans CJK JP Medium' +set xfont_size=16 +if $?batchmode +else +pre_set strict_errorhandling +unset ngdebug +*save outputs and specials +save x1.x1.x1.7 V(9) V(10) V(11) V(身12) V(Я13) +run +display +* plot the inputs, use offset to plot on top of each other +plot v(1) v(2)+4 v(3)+8 v(4)+12 v(5)+16 v(6)+20 v(7)+24 v(8)+28 +* plot the outputs, use offset to plot on top of each other +plot v(9) v(10)+4 v(11)+8 v(身12)+12 v(Я13)+16 +endif +.endc + +.END diff --git a/examples/utf-8/стекло/있어요/ext-utf8-1.cir b/examples/utf-8/стекло/있어요/ext-utf8-1.cir new file mode 100644 index 000000000..d21144c51 --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-1.cir @@ -0,0 +1,39 @@ +* test de titré +.control + +* for CYGWIN +setcs xfont='Noto Sans CJK JP Medium' +set xfont_size=16 +* for LINUX +*setcs xfont='Noto Sans Korean' + +let x = vector(5) +let y = exp(x) +setcs wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 11' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 12 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 13 私はガラスを食べられます。それは私を傷つけません' loglog +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 14 我能吞下玻璃而不伤身体。' loglog + +* for CYGWIN +*setcs xfont='Adobe Times' +* for LINUX +setcs xfont='Efont Biwidth' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 15' loglog + +write D:/Spice_general/tests/utf-8/'стекло'/'있어요'/ext-utf8-1.out x y + +setcs sourcepath = ( 'D:/Spice_general/tests/utf-8/стекло/있어요' ) +*setcs sourcepath = ( './utf-8/стекло/있어요' ) +source ext-utf8-2.cir + +*source 'D:/Spice_general/tests/utf-8/стекло/있어요/ext-utf8-2.cir' + +echo 私はガラスを食べられます。それは私を傷つけません +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 + +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir b/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir new file mode 100644 index 000000000..0253a4c77 --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-2-있어요.cir @@ -0,0 +1,46 @@ +* test de titré +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=1 +set color2=rgb:F/0/0 +*setcs hcopyfont=Arial +* +*setcs hcopyfont='Nimbus Mono-Regular' +* for CYGWIN +setcs hcopyfont='NimbusMonL-Bold' +*setcs hcopyfont='URWGothicL-Book' +set hcopyfontsize=14 + +* for CYGWIN +setcs xfont='Noto Sans CJK JP Medium' +set xfont_size=18 +*setcs xfont='Noto Sans Japanese' + +let x = vector(5) +let y = exp(x) +setcs wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 22 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 23 私はガラスを食べられます。それは私を傷つけません' loglog +*LINUX +*setcs xfont='Noto Sans Korean' +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 24 我能吞下玻璃而不伤身体。' loglog +* for CYGWIN +setcs xfont='Times New Roman' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 25' loglog + +hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +* for MS Windows only +shell Start /B plot_5.ps +* for CYGWIN +*shell xterm -e gs plot_5.ps & + +echo 些 𣎏 世 咹 水 晶 𦓡 空 𣎏 害 咦 +echo אני יכול לאכול זכוכית וזה לא מזיק לי. + +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-2.cir b/examples/utf-8/стекло/있어요/ext-utf8-2.cir new file mode 100644 index 000000000..ca1971862 --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-2.cir @@ -0,0 +1,73 @@ +* test de titré +* utf-8 UNICODE tests +* text snippets are from http://kermitproject.org/utf8.html +* English translation: I can eat glass and it doesn't hurt me. + +.control +set hcopydevtype = postscript +set hcopypscolor=0 +set hcopypstxcolor=1 +set hcopyscale=1 +* 16 bit color for Linux +set color2=rgb:F/0/0 +* 256 bit color for Windows or Linux +set color2=rgb:FF/0/0 +*setcs hcopyfont=Arial +* +*setcs hcopyfont='Nimbus Mono-Regular' +* for CYGWIN +setcs hcopyfont='NimbusMonL-Bold' +set hcopyfontsize=14 + +* the data to be plotted +let x = vector(5) +let y = exp(x) + +* MS Windows +setcs wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' + +* Linux, CYGWIN +* Use font (*.ttc) from Cygwin distribution +setcs xfont='Noto Sans CJK JP Light' +set xfont_size=16 +set color2=rgb:0/FF/0 +set xbrushwidth=2 +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 22 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +set color2=rgb:0/FF/FF +set xbrushwidth=4 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 23 私はガラスを食べられます。それは私を傷つけません' loglog +set color2=rgbd:255/0/255 +set xbrushwidth=8 +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel '나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 24 我能吞下玻璃而不伤身体。' loglog +unset color2 +set color0=white +* https://www.fontsc.com/font/tag/arabic +setcs xfont='Lateef' +set xfont_size=22 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني ' title 'Titré French Arabic 25' loglog +plot y vs x+0.001 xlabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني ' ylabel 'Jeg kan spise glas, det gør ikke ondt på mig. 26 ' title 'Titré Arabic 26' loglog + +* https://www.fontsc.com/font/tag/hebrew +setcs xfont='Alef' +set xfont_size=18 +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' אני יכול לאכול זכוכית וזה לא מזיק לי. ' title 'Titré French Arabic 27' loglog +plot y vs x+0.001 xlabel ' אני יכול לאכול זכוכית וזה לא מזיק לי. ' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré Arabic 28' loglog + +hardcopy plot_6.ps y vs x xlabel 'Labellisé X' ylabel 'Jeg kan spise glas, det gør ikke ondt på mig.' title 'Titré Äü @µ€~' + +* for MS Windows only +*shell Start /B plot_5.ps +* for CYGWIN +*shell xterm -e gs plot_5.ps & +shell gv plot_6.ps & + +echo 些 𣎏 世 咹 水 晶 𦓡 空 𣎏 害 咦 +echo אני יכול לאכול זכוכית וזה לא מזיק לי. +echo ' أنا قادر على أكل الزجاج و هذا لا يؤلمني ' + +gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-3.cir b/examples/utf-8/стекло/있어요/ext-utf8-3.cir new file mode 100644 index 000000000..e3c17ad71 --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-3.cir @@ -0,0 +1,62 @@ +* test de titré +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopypstxcolor=21 +set hcopyscale=1 +set color2=rgb:F/0/0 +setcs hcopyfont=Arial +set hcopyfontsize=18 + +let x = vector(5) +let y = exp(x) +setcs wfont=Arial +set wfont_size=18 +setcs xfont='Noto Sans CJK JP Medium' +*set xfont_size=16 + +set xgridwidth=4 +set xbrushwidth=1 + +set nolegend + +*hardcopy + +**plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +**gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +set xgridwidth=1 +set xbrushwidth=4 + +**plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 私はガラスを食べられます。それは私を傷つけません' loglog +*plot y vs x+0.001 xlabel 'Labellisé X' title 'Titré' loglog +plot y vs x xlabel '래도 아프지 않아요' ylabel '私はガラスを食べられます' title ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' + +* With Linux the next one requires: export LC_CTYPE ="de_DE.UTF-8" +**gnuplot test2.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +if ($oscompiled = 1) or ($oscompiled = 8) + shell Start /B plot_5.ps +endif +if ($oscompiled = 2) + shell xterm -e gs plot_5.ps & +endif +if ($oscompiled = 6) + shell gv plot_5.ps & +endif +if ($oscompiled = 7) + shell open -a Preview plot_5.ps & +endif + +wrdata test.out y vs x +**asciiplot atest.out y vs x + +echo 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요 +echo 私はガラスを食べられます。それは私を傷つけません +echo 我能吞下玻璃而不伤身体 + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/ext-utf8-4.cir b/examples/utf-8/стекло/있어요/ext-utf8-4.cir new file mode 100644 index 000000000..e9b4f49e3 --- /dev/null +++ b/examples/utf-8/стекло/있어요/ext-utf8-4.cir @@ -0,0 +1,40 @@ +* test de titré それは私を傷つけません +.control +set hcopydevtype = postscript +set hcopypscolor=1 +set hcopyscale=0.5 +set color2=rgb:F/0/0 +*setcs hcopyfont=Arial +* for CYGWIN +setcs hcopyfont='NimbusMono-Regular' +set hcopyfontsize=14 + +* for CYGWIN +setcs xfont='Noto Sans CJK JP Medium' +set xfont_size=16 + +let x = vector(5) +let y = exp(x) +setcs wfont='Arial' +set wfont_size=18 +plot y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y: ÜüÖöÄäÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ' title 'Titré 21' +plot y vs x xlabel '我能吞下玻璃而不伤身体' ylabel 'Я могу есть стекло, оно мне не вредит' title 'Titré 22 أنا قادر على أكل الزجاج و هذا لا يؤلمني.' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré 23 私はガラスを食べられます。それは私を傷つけません' loglog +plot y vs x+0.001 xlabel 'Titré 私はガラスを食べられます。それは私を傷つけません' ylabel 'Titré 24 나는 유리를 먹을 수 있어요. 그래도 아프지 않아요' title 'Titré 我能吞下玻璃而不伤身体。' loglog +* for CYGWIN +setcs xfont='Times New Roman' +plot y vs x+0.001 xlabel 'Labellisé X' ylabel ' أنا قادر على أكل الزجاج و هذا لا يؤلمني.' title 'Titré 25' loglog + +hardcopy plot_5.ps y vs x xlabel 'Labellisé X' ylabel 'Labellisé Y' title 'Titré Äü @µ€~' +* for MS Windows only +*shell Start /B plot_5.ps +* for CYGWIN +shell xterm -e gs plot_5.ps & + +echo 3 ' 些 𣎏 世 咹 水 晶 𦓡 空 𣎏 害 咦 ' +echo 4 אני יכול לאכול זכוכית וזה לא מזיק לי. + +*gnuplot test.gn y vs x xlabel 'Labellisé X' ylabel 'tüTÄtö Äü @µ€~' title 'ฉันกินกระจกได้ แต่มันไม่ทำให้ฉันเจ็บ ' + +*quit +.endc diff --git a/examples/utf-8/стекло/있어요/utf-8-inv.cir b/examples/utf-8/стекло/있어요/utf-8-inv.cir new file mode 100644 index 000000000..f11d9efa9 --- /dev/null +++ b/examples/utf-8/стекло/있어요/utf-8-inv.cir @@ -0,0 +1,52 @@ + 4 BIT ALL-NAND-GATE BINARY ADDER with node names 能 and せん + +.param W咦 = 3u + +*** SUBCIRCUIT DEFINITIONS +.SUBCKT NAдND 能 せん out VDD +* NODES: INPUT(2), OUTPUT, VCC +M1 out せん Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M2 net.1 せん 0 0 n1 W='W咦' L=0.35u pd=9u ad=9p ps=9u as=9p +M3 out 能 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M4 out 能 net.1 0 n1 W='W咦' L=0.35u pd=9u ad=9p ps=9u as=9p +.ENDS NAдND + +X않1 1 は2 7 99 NAдND + +*** POWER +V을을 99 0 DC 3.3V + +*** ALL INPUTS +VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS) +VIN1B は2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) + +.option noinit acct +.TRAN 500p 6400NS +* save inputs +.save V(1) V(は2) V(7) + +* use BSIM3 model with default parameters +.model n1 nmos level=49 version=3.3.0 +.model p1 pmos level=49 version=3.3.0 +*.include ./Modelcards/modelcard32.nmos +*.include ./Modelcards/modelcard32.pmos + +.control +* for CYGWIN +setcs xfont='Noto Sans CJK JP Medium' +set xfont_size=16 +if $?batchmode +else +pre_set strict_errorhandling +unset ngdebug +*save outputs and specials +run +display +* plot the inputs and outputs, use offset to plot on top of each other +let れ1 = 4 +let れ2 = 8 +plot v(1) v(は2)+れ1 v(7)+れ2 +endif +.endc + +.END diff --git a/examples/utf-8/стекло/있어요/utf-8-inv_w.cir b/examples/utf-8/стекло/있어요/utf-8-inv_w.cir new file mode 100644 index 000000000..1a0a1c588 --- /dev/null +++ b/examples/utf-8/стекло/있어요/utf-8-inv_w.cir @@ -0,0 +1,53 @@ + 4 BIT ALL-NAND-GATE BINARY ADDER with node names 能 and せん + +.param W咦 = 3u + +*** SUBCIRCUIT DEFINITIONS +.SUBCKT NAдND 能 せん out VDD +* NODES: INPUT(2), OUTPUT, VCC +M1 out せん Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M2 net.1 せん 0 0 n1 W='W咦' L=0.35u pd=9u ad=9p ps=9u as=9p +M3 out 能 Vdd Vdd p1 W=7.5u L=0.35u pd=13.5u ad=22.5p ps=13.5u as=22.5p +M4 out 能 net.1 0 n1 W='W咦' L=0.35u pd=9u ad=9p ps=9u as=9p +.ENDS NAдND + +X않1 1 は2 7 99 NAдND + +*** POWER +V을을 99 0 DC 3.3V + +*** ALL INPUTS +VIN1A 1 0 DC 0 PULSE(0 3 0 5NS 5NS 20NS 50NS) +VIN1B は2 0 DC 0 PULSE(0 3 0 5NS 5NS 30NS 100NS) + +.option noinit acct +.TRAN 500p 500NS +* save inputs +.save V(1) V(は2) V(7) + +* use BSIM3 model with default parameters +.model n1 nmos level=49 version=3.3.0 +.model p1 pmos level=49 version=3.3.0 +*.include ./Modelcards/modelcard32.nmos +*.include ./Modelcards/modelcard32.pmos + +.control +* for CYGWIN +setcs xfont='Noto Sans CJK JP Medium' +set xfont_size=16 + +if $?batchmode +else +pre_set strict_errorhandling +unset ngdebug +*save outputs and specials +run +display +* plot the inputs and outputs, use offset to plot on top of each other +let れ1 = 4 +let れ2 = 8 +plot v(1) v(は2)+れ1 v(7)+れ2 +endif +.endc + +.END diff --git a/examples/various/nmos_out_BSIM330.sp b/examples/various/nmos_out_BSIM330.sp new file mode 100644 index 000000000..20338b5a3 --- /dev/null +++ b/examples/various/nmos_out_BSIM330.sp @@ -0,0 +1,37 @@ +***** NMOS Transistor BSIM3 (Id-Vds) with Rd *** + +M1 2 1 3 4 n1 W=1u L=0.35u Pd=1.5u Ps=1.5u ad=1.5p as=1.5p +vgs 1 0 3.5 +vds 2 0 0.1 +vss 3 0 0 +vbs 4 0 0 + +* drain series resistor +R2 2 22 1k +M2 22 1 32 4 n1 W=1u L=0.35u Pd=1.5u Ps=1.5u ad=1.5p as=1.5p +vss2 32 0 0 + + +.options Temp=27.0 + +* BSIM3v3.3.0 model with modified default parameters 0.18m +.model n1 nmos level=49 version=3.3.0 tox=3.5n nch=2.4e17 nsub=5e16 vth0=0.15 +.model p1 pmos level=49 version=3.3.0 tox=3.5n nch=2.5e17 nsub=5e16 vth0=-0.15 + +.control +set xgridwidth=2 +set xbrushwidth=3 +dc vds 0 2 0.05 vgs 0 2 0.4 +set nolegend +plot vss#branch title 'Drain current versus drain voltage' xlabel 'Drain voltage' ylabel 'Drain current' +unset nolegend +set color0=white +plot vss2#branch vs v(22) title 'Series resistor: Drain current versus drain voltage' xlabel 'Drain voltage' ylabel 'Drain current' +.endc + +.end + + + + + diff --git a/examples/various/nmos_pmos_BSIM330.sp b/examples/various/nmos_pmos_BSIM330.sp index 20b266e7c..52c5d512e 100644 --- a/examples/various/nmos_pmos_BSIM330.sp +++ b/examples/various/nmos_pmos_BSIM330.sp @@ -26,6 +26,8 @@ vbsp 44 0 0 *.model p1 PMOS level=49 version=3.3.0 .control +set xgridwidth=2 +set xbrushwidth=3 dc vgs 0 1.5 0.05 vbs 0 -2.5 -0.5 plot vss#branch dc vds 0 2 0.05 vgs 0 2 0.4 diff --git a/src/frontend/Makefile.am b/src/frontend/Makefile.am index 46000d289..2ebd79e19 100644 --- a/src/frontend/Makefile.am +++ b/src/frontend/Makefile.am @@ -69,8 +69,6 @@ libfte_la_SOURCES = \ com_sysinfo.c \ com_unset.c \ com_unset.h \ - com_xgraph.c \ - com_xgraph.h \ completion.h \ control.h \ control.c \ diff --git a/src/frontend/breakp2.c b/src/frontend/breakp2.c index 14c2d7f4b..56cc9f463 100644 --- a/src/frontend/breakp2.c +++ b/src/frontend/breakp2.c @@ -12,7 +12,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice/ftedefs.h" #include "ngspice/dvec.h" #include "ngspice/ftedebug.h" -#include "quote.h" #include "breakp2.h" diff --git a/src/frontend/com_alias.c b/src/frontend/com_alias.c index c1d06cc13..d417b703c 100644 --- a/src/frontend/com_alias.c +++ b/src/frontend/com_alias.c @@ -152,7 +152,6 @@ cp_setalias(char *word, wordlist *wlist) al->al_name = copy(word); al->al_text = wl_copy(wlist); - cp_striplist(al->al_text); /* We can afford to not worry about the bits, because before the * keyword lookup is done the alias is evaluated. Make everything * file completion, just in case... */ diff --git a/src/frontend/com_chdir.c b/src/frontend/com_chdir.c index 4beee8860..a8cf8d83e 100644 --- a/src/frontend/com_chdir.c +++ b/src/frontend/com_chdir.c @@ -11,7 +11,6 @@ #endif #include "com_chdir.h" -#include "quote.h" #include "ngspice/cpextern.h" diff --git a/src/frontend/com_compose.c b/src/frontend/com_compose.c index 4c80a8170..099e68c8b 100644 --- a/src/frontend/com_compose.c +++ b/src/frontend/com_compose.c @@ -11,8 +11,6 @@ #include "ngspice/fteext.h" #include "ngspice/cpextern.h" #include "ngspice/randnumb.h" - -#include "quote.h" #include "com_compose.h" #include "completion.h" diff --git a/src/frontend/com_display.c b/src/frontend/com_display.c index 37fa68251..1fef086a7 100644 --- a/src/frontend/com_display.c +++ b/src/frontend/com_display.c @@ -5,7 +5,6 @@ #include "ngspice/cpextern.h" #include "com_display.h" -#include "quote.h" #include "variable.h" #include "plotting/plotting.h" #include "plotting/pvec.h" diff --git a/src/frontend/com_echo.c b/src/frontend/com_echo.c index 28c030f55..75d411130 100644 --- a/src/frontend/com_echo.c +++ b/src/frontend/com_echo.c @@ -7,7 +7,6 @@ #include "ngspice/bool.h" #include "com_echo.h" -#include "quote.h" #include "ngspice/cpextern.h" diff --git a/src/frontend/com_hardcopy.c b/src/frontend/com_hardcopy.c index 39aa0baed..2a7cba1a8 100644 --- a/src/frontend/com_hardcopy.c +++ b/src/frontend/com_hardcopy.c @@ -66,17 +66,23 @@ void com_hardcopy(wordlist *wl) /* enable screen plot selection for these display types */ foundit = 0; - - // PushGraphContext(currentgraph); - #ifdef HAS_WINGUI if (!wl && hc_button) { char *psfname; GRAPH *tempgraph; - if (DevSwitch(devtype)) { + /* initialze PS by calling PS_Init() */ + if (DevSwitch(devtype)) + return; + if (currentgraph) + tempgraph = CopyGraph(currentgraph); + else { + fprintf(stderr, + "No parameters for hardcopy command, not previous plot:\n"); + fprintf(stderr, " Command hardcopy cannot be executed\n\n"); + DevSwitch(NULL); return; } - tempgraph = CopyGraph(currentgraph); + /* change .tmp to .ps */ psfname = strchr(fname, '.'); if (psfname) { @@ -150,7 +156,7 @@ void com_hardcopy(wordlist *wl) PushGraphContext(currentgraph); if (!foundit) { - if (!wl) { + if (!wl && cp_getvar("interactive", CP_BOOL, NULL, 0)) { char *buf2; outmenuprompt("which variable ? "); buf2 = prompt(cp_in); diff --git a/src/frontend/com_setscale.c b/src/frontend/com_setscale.c index fb0d00297..024bb043d 100644 --- a/src/frontend/com_setscale.c +++ b/src/frontend/com_setscale.c @@ -3,7 +3,6 @@ #include "ngspice/dvec.h" #include "com_setscale.h" -#include "quote.h" #include "ngspice/cpextern.h" #include "vectors.h" #include "plotting/plotting.h" diff --git a/src/frontend/com_strcmp.c b/src/frontend/com_strcmp.c index 5d259cda8..014a8025a 100644 --- a/src/frontend/com_strcmp.c +++ b/src/frontend/com_strcmp.c @@ -4,7 +4,6 @@ #include "ngspice/wordlist.h" #include "com_strcmp.h" -#include "quote.h" #include "variable.h" diff --git a/src/frontend/commands.c b/src/frontend/commands.c index be8d8e394..119bd1dcc 100644 --- a/src/frontend/commands.c +++ b/src/frontend/commands.c @@ -47,7 +47,6 @@ #include "com_let.h" #include "com_plot.h" #include "com_setscale.h" -#include "com_xgraph.h" #include "com_gnuplot.h" #include "com_state.h" #include "com_chdir.h" @@ -205,10 +204,6 @@ struct comm spcp_coms[] = { { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, NULL, "varname ... : Perform matrix transposition on multi-D vectors." } , - { "xgraph", com_xgraph, FALSE, TRUE, - { 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS, - NULL, - "file plotargs : Send plot to Xgraph-11." } , { "gnuplot", com_gnuplot, FALSE, TRUE, { 1, 041000, 041000, 041000 }, E_DEFHMASK, 2, LOTS, NULL, @@ -689,10 +684,6 @@ struct comm nutcp_coms[] = { { 040000, 040000, 040000, 040000 }, E_DEFHMASK, 1, LOTS, NULL, "varname ... : Perform matrix transposition on multi-D vectors." } , - { "xgraph", com_xgraph, FALSE, TRUE, - { 1, 041000, 041000, 041000 }, E_DEFHMASK, 1, LOTS, - NULL, - "file plotargs : Send plot to Xgraph-11." } , { "gnuplot", com_gnuplot, FALSE, TRUE, { 1, 041000, 041000, 041000 }, E_DEFHMASK, 2, LOTS, NULL, diff --git a/src/frontend/control.c b/src/frontend/control.c index e322df45f..157a43b75 100644 --- a/src/frontend/control.c +++ b/src/frontend/control.c @@ -192,9 +192,6 @@ docommand(wordlist *wlist) return; } - /* Get rid of all the 8th bits now... */ - cp_striplist(wlist); - s = wlist->wl_word; /* Look for the command in the command list. */ diff --git a/src/frontend/cpitf.c b/src/frontend/cpitf.c index 246012c66..f4d984097 100644 --- a/src/frontend/cpitf.c +++ b/src/frontend/cpitf.c @@ -262,7 +262,6 @@ ft_cpinit(void) { wordlist *wl; wl = cp_doglob(cp_lexer(buf)); - cp_striplist(wl); com_set(wl); wl_free(wl); } @@ -339,8 +338,6 @@ cp_istrue(wordlist *wl) return FALSE; /* backquote '`' substitution */ wl = cp_bquote(wl); - /* strip bit number eight */ - cp_striplist(wl); /* parse the condition */ names = ft_getpnames(wl, TRUE); diff --git a/src/frontend/display.c b/src/frontend/display.c index 0faa71b27..797cd0103 100644 --- a/src/frontend/display.c +++ b/src/frontend/display.c @@ -233,9 +233,9 @@ DevClear(void) void -DevDrawLine(int x1, int y1, int x2, int y2) +DevDrawLine(int x1, int y1, int x2, int y2, bool isgrid) { - dispdev->DrawLine (x1, y1, x2, y2); + dispdev->DrawLine (x1, y1, x2, y2, isgrid); } @@ -275,9 +275,9 @@ SetLinestyle(int linestyleid) void -SetColor(int colorid) +SetColor(int colorid, GRAPH *graph) { - dispdev->SetColor (colorid); + dispdev->SetColor (colorid, graph); } diff --git a/src/frontend/display.h b/src/frontend/display.h index 6d4f10bf5..df7944d21 100644 --- a/src/frontend/display.h +++ b/src/frontend/display.h @@ -17,13 +17,13 @@ void DevInit(void); int NewViewport(GRAPH *pgraph); void DevClose(void); void DevClear(void); -void DevDrawLine(int x1, int y1, int x2, int y2); +void DevDrawLine(int x1, int y1, int x2, int y2, bool isgrid); void DevDrawArc(int x0, int y0, int radius, double theta, double delta_theta); void DevDrawText(char *text, int x, int y, int angle); void DefineColor(int colorid, double red, double green, double blue); void DefineLinestyle(int linestyleid, int mask); void SetLinestyle(int linestyleid); -void SetColor(int colorid); +void SetColor(int colorid, GRAPH* graph); void DevUpdate(void); void DatatoScreen(GRAPH *graph, double x, double y, int *screenx, int *screeny); void Input(REQUEST *request, RESPONSE *response); diff --git a/src/frontend/hpgl.c b/src/frontend/hpgl.c index 865bbb62c..77be5e6d1 100644 --- a/src/frontend/hpgl.c +++ b/src/frontend/hpgl.c @@ -201,8 +201,10 @@ int GL_Clear(void) } -int GL_DrawLine(int x1, int y1, int x2, int y2) +int +GL_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { + NG_IGNORE(isgrid); /* note: this is not extendible to more than one graph => will have to give NewViewport a writeable graph XXX */ @@ -250,6 +252,8 @@ int GL_Arc(int x0, int y0, int r, double theta, double delta_theta) int GL_Text(char *text, int x, int y, int angle) { + NG_IGNORE(angle); + /* move to (x, y) */ NG_IGNORE(angle); @@ -287,9 +291,9 @@ int GL_SetLinestyle(int linestyleid) } -/* ARGSUSED */ -int GL_SetColor(int colorid) +int GL_SetColor(int colorid, GRAPH* graph) { + NG_IGNORE(graph); fprintf(plotfile, "SP %d;", colorid); return 0; diff --git a/src/frontend/init.c b/src/frontend/init.c index 5e963e585..fe494a34d 100644 --- a/src/frontend/init.c +++ b/src/frontend/init.c @@ -30,4 +30,41 @@ cp_init(void) /* io redirection in streams.c: cp_in set to cp_curin etc. */ cp_ioreset(); + + /*set a variable oscompiled containing the OS at compile time + [0], Other + [1], MINGW for MS Windows + [2], Cygwin for MS Windows + [3], FreeBSD + [4], OpenBSD + [5], Solaris + [6], Linux + [7], macOS + [8], Visual Studio for MS Windows + The variable may be used in a .control section to perform OS + specific actions (setting fonts etc.). + */ + int itmp; +#if OS_COMPILED == 1 + itmp = 1; +#elif OS_COMPILED == 2 + itmp = 2; +#elif OS_COMPILED == 3 + itmp = 3; +#elif OS_COMPILED == 4 + itmp = 4; +#elif OS_COMPILED == 5 + itmp = 5; +#elif OS_COMPILED == 6 + itmp = 6; +#elif OS_COMPILED == 7 + itmp = 7; +#else + itmp = 0; +#endif + /* not using configure.ac */ +#ifdef _MSC_VER + itmp = 8; +#endif + cp_vset("oscompiled", CP_NUM, &itmp); } diff --git a/src/frontend/inp.c b/src/frontend/inp.c index 031f5c591..1726f56e7 100644 --- a/src/frontend/inp.c +++ b/src/frontend/inp.c @@ -79,6 +79,11 @@ extern bool ft_batchmode; extern void exec_controls(wordlist *controls); #endif +/* display the source file name in the source window */ +#ifdef HAS_WINGUI +extern void SetSource(char *Name); +#endif + /* structure used to save expression parse trees for .model and * device instance lines */ @@ -1605,6 +1610,10 @@ com_source(wordlist *wl) if (ft_nutmeg || substring(INITSTR, owl->wl_word) || substring(ALT_INITSTR, owl->wl_word)) inp_spsource(fp, TRUE, tempfile ? NULL : wl->wl_word, FALSE); else { +#ifdef HAS_WINGUI + /* set the source window */ + SetSource(wl->wl_word); +#endif /* Save path name for use in XSPICE fopen_with_path() */ if (Infile_Path) tfree(Infile_Path); diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 4888f4628..ea5a05bcf 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -181,6 +181,15 @@ static void pspice_compat_a(struct card *oldcard); static struct card *ltspice_compat(struct card *oldcard); static void ltspice_compat_a(struct card *oldcard); +#if defined(__MINGW32__) || defined(_MSC_VER) +#ifndef EXT_ASC +static int newstat(const char *name, struct _stat *st); +#endif +#endif +#ifndef EXT_ASC +static void utf8_syntax_check(struct card *deck); +#endif + struct inp_read_t { struct card *cc; int line_number; @@ -619,6 +628,10 @@ struct card *inp_readall(FILE *fp, const char *dir_name, struct card *working = cc->nextcard; delete_libs(); + +#ifndef EXT_ASC + utf8_syntax_check(working); +#endif /* some syntax checks, including title line */ inp_check_syntax(cc); @@ -1282,6 +1295,13 @@ FILE *inp_pathopen(const char *name, const char *mode) } /* end of function inp_pathopen */ +/* for MultiByteToWideChar */ +#if defined(__MINGW32__) || defined(_MSC_VER) +#ifndef EXT_ASC +#undef BOOLEAN +#include +#endif +#endif /*-------------------------------------------------------------------------* Look up the variable sourcepath and try everything in the list in order @@ -1317,6 +1337,17 @@ static char *inp_pathresolve(const char *name) /* just try it */ if (stat(name, &st) == 0) return copy(name); + +#if !defined(EXT_ASC) && (defined(__MINGW32__) || defined(_MSC_VER)) + wchar_t wname[BSIZE_SP]; + if (MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, 2 * (int)strlen(name) + 1) == 0) { + fprintf(stderr, "UTF-8 to UTF-16 conversion failed with 0x%x\n", GetLastError()); + fprintf(stderr, "%s could not be converted\n", name); + return NULL; + } + if (_waccess(wname, 0) == 0) + return copy(name); +#endif /* fail if this was an absolute filename or if there is no sourcepath var */ @@ -1333,7 +1364,6 @@ static char *inp_pathresolve(const char *name) switch (v->va_type) { case CP_STRING: - cp_wstrip(v->va_string); rc_ds = ds_cat_printf(&ds, "%s%s%s", v->va_string, DIR_PATHSEP, name); break; @@ -2400,11 +2430,6 @@ void inp_casefix(char *string) } if (string) while (*string) { -#ifdef HAS_ASCII - /* ((*string) & 0177): mask off all but the first seven bits, - * 0177: octal */ - *string = (char) strip(*string); -#endif if (*string == '"') { *string++ = ' '; while (*string && *string != '"') @@ -6910,10 +6935,10 @@ static int inp_vdmos_model(struct card *deck) wl_append_word(&wl, &wl, copy_substring(curr_line, cut_line)); wlb = wl; if (strstr(cut_line, "pchan")) { - wl_append_word(NULL, &wl, "vdmosp ("); + wl_append_word(NULL, &wl, copy("vdmosp (")); } else { - wl_append_word(NULL, &wl, "vdmosn ("); + wl_append_word(NULL, &wl, copy("vdmosn (")); } cut_line = cut_line + 5; @@ -6924,17 +6949,20 @@ static int inp_vdmos_model(struct card *deck) while (cut_line && *cut_line) { token = gettok_model(&cut_line); if (!ciprefix("pchan", token) && !ciprefix("ron=", token) && - !ciprefix("vds=", token) && !ciprefix("qg=", token) && - !ciprefix("mfg=", token) && !ciprefix("nchan", token)) + !ciprefix("vds=", token) && !ciprefix("qg=", token) && + !ciprefix("mfg=", token) && !ciprefix("nchan", token)) wl_append_word(NULL, &wl, token); + else + tfree(token); if (*cut_line == ')') { - wl_append_word(NULL, &wl, ")"); + wl_append_word(NULL, &wl, copy(")")); break; } } new_line = wl_flatten(wlb); tfree(card->line); card->line = new_line; + wl_free(wlb); } /* we have a VDMOS instance line with 'tnodeout' and thus need exactly 5 nodes */ @@ -8604,3 +8632,82 @@ static void inp_rem_unused_models(struct nscope *root, struct card *deck) // disable unused .model lines, and free the models assoc lists rem_unused_xxx(root); } + +/* Markus Kuhn -- 2005-03-30 + * License: Modified BSD (see http://www.cl.cam.ac.uk/~mgk25/short-license.html) + * The utf8_check() function scans the '\0'-terminated string starting + * at s. It returns a pointer to the first byte of the first malformed + * or overlong UTF-8 sequence found, or NULL if the string contains + * only correct UTF-8. It also spots UTF-8 sequences that could cause + * trouble if converted to UTF-16, namely surrogate characters + * (U+D800..U+DFFF) and non-Unicode positions (U+FFFE..U+FFFF).*/ +#ifndef EXT_ASC +static unsigned char* +utf8_check(unsigned char *s) +{ + while (*s) { + if (*s < 0x80) + /* 0xxxxxxx */ + s++; + else if ((s[0] & 0xe0) == 0xc0) { + /* 110XXXXx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[0] & 0xfe) == 0xc0) /* overlong? */ + return s; + else + s += 2; + } + else if ((s[0] & 0xf0) == 0xe0) { + /* 1110XXXX 10Xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || /* overlong? */ + (s[0] == 0xed && (s[1] & 0xe0) == 0xa0) || /* surrogate? */ + (s[0] == 0xef && s[1] == 0xbf && + (s[2] & 0xfe) == 0xbe)) /* U+FFFE or U+FFFF? */ + return s; + else + s += 3; + } + else if ((s[0] & 0xf8) == 0xf0) { + /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ + if ((s[1] & 0xc0) != 0x80 || + (s[2] & 0xc0) != 0x80 || + (s[3] & 0xc0) != 0x80 || + (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || /* overlong? */ + (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) /* > U+10FFFF? */ + return s; + else + s += 4; + } + else + return s; + } + + return NULL; +} + +/* Scan through input deck and check for utf-8 syntax errors */ +static void +utf8_syntax_check(struct card *deck) +{ + struct card *card; + unsigned char *s; + + for (card = deck; card; card = card->nextcard) { + + char *curr_line = card->line; + + if (*curr_line == '*') + continue; + + s = utf8_check((unsigned char*)curr_line); + + if (s) { + fprintf(stderr, "Error: UTF-8 syntax error in line %d at %s\n", card->linenum_orig, s); + controlled_exit(1); + } + } +} +#endif + diff --git a/src/frontend/newcoms.c b/src/frontend/newcoms.c index 34ee8370d..21723a2b9 100644 --- a/src/frontend/newcoms.c +++ b/src/frontend/newcoms.c @@ -14,7 +14,6 @@ Copyright 1992 Regents of the University of California. All rights reserved. #include "ngspice/stringskip.h" #include "newcoms.h" -#include "quote.h" /* diff --git a/src/frontend/numparam/mystring.c b/src/frontend/numparam/mystring.c index d699522f6..8918de630 100644 --- a/src/frontend/numparam/mystring.c +++ b/src/frontend/numparam/mystring.c @@ -142,7 +142,7 @@ alfa(char c) return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || - c == '_' || c == '[' || c == ']'; + c == '_' || c == '[' || c == ']' || ((c) & 0200); } diff --git a/src/frontend/numparam/spicenum.c b/src/frontend/numparam/spicenum.c index 52255a050..b9cde18fe 100644 --- a/src/frontend/numparam/spicenum.c +++ b/src/frontend/numparam/spicenum.c @@ -81,7 +81,7 @@ stripsomespace(DSTRINGPTR dstr_p, bool incontrol) char *s = ds_get_buf(dstr_p); int i = 0; - while (s[i] && (s[i] <= ' ')) + while (s[i] && ((unsigned char)s[i] <= ' ')) i++; if ((i > 0) && s[i] && strchr(markers, s[i])) @@ -116,7 +116,7 @@ stripbraces(DSTRINGPTR dstr_p) pscopy(&tstr, s, brace); - if (brace[-1] > ' ') + if ((unsigned char)brace[-1] > ' ') cadd(&tstr, ' '); cadd(&tstr, ' '); @@ -127,7 +127,7 @@ stripbraces(DSTRINGPTR dstr_p) } cadd(&tstr, ' '); - if (*j_ptr >= ' ') + if ((unsigned char)(* j_ptr) >= ' ') cadd(&tstr, ' '); int ilen = (int) ds_get_length(&tstr); diff --git a/src/frontend/numparam/xpressn.c b/src/frontend/numparam/xpressn.c index 78fb231c9..006b0dc60 100644 --- a/src/frontend/numparam/xpressn.c +++ b/src/frontend/numparam/xpressn.c @@ -509,15 +509,15 @@ defsubckt(dico_t *dico, const struct card *card) while (*s && (*s != '.')) s++; /* skip 1st dotword */ - while (*s && (*s > ' ')) + while (*s && ((unsigned char) (*s) > ' ')) s++; - while (*s && (*s <= ' ')) + while (*s && ((unsigned char) (*s) <= ' ')) s++; /* skip blank */ s_end = s; - while (*s_end && (*s_end > ' ')) + while (*s_end && ((unsigned char) (*s_end) > ' ')) s_end++; if (s_end > s) { @@ -574,7 +574,7 @@ keyword(const char *keys, const char *s, const char *s_end) const char *p = s; while ((p < s_end) && (*p == *keys)) p++, keys++; - if ((p >= s_end) && (*keys <= ' ')) + if ((p >= s_end) && ((unsigned char) (*keys) <= ' ')) return j; keys = strchr(keys, ' '); if (!keys) @@ -723,7 +723,7 @@ fetchoperator(dico_t *dico, level = 8; } else { state = S_init; - if (c > ' ') + if ((unsigned char) c > ' ') error = message(dico, "Syntax error: letter [%c]\n", c); } @@ -859,7 +859,7 @@ formula(dico_t *dico, const char *s, const char *s_end, bool *perror) } /* trim trailing whitespace */ - while ((s_end > s) && (s_end[-1] <= ' ')) + while ((s_end > s) && ((unsigned char) (s_end[-1]) <= ' ')) s_end--; state = S_init; @@ -1222,7 +1222,7 @@ getexpress(nupa_type *type, DSTRINGPTR tstr_p, const char *s) const char *p; nupa_type tpe; - while ((s < s_end - 1) && (*s <= ' ')) + while ((s < s_end - 1) && ((unsigned char)(* s) <= ' ')) s++; /*white space ? */ if (*s == '"') { /* string constant */ @@ -1235,7 +1235,7 @@ getexpress(nupa_type *type, DSTRINGPTR tstr_p, const char *s) do p++; - while ((p < s_end) && (*p <= ' ')); + while ((p < s_end) && ((unsigned char)(*p) <= ' ')); tpe = NUPA_STRING; @@ -1309,11 +1309,11 @@ nupa_assignment(dico_t *dico, const char *s, char mode) DS_CREATE(tstr, 200); /* temporary dstrings */ DS_CREATE(ustr, 200); - while ((p < s_end) && (*p <= ' ')) + while ((p < s_end) && ((unsigned char) (*p) <= ' ')) p++; if (*p == '.') /* skip any dot keyword */ - while (*p > ' ') + while ((unsigned char) (*p) > ' ') p++; while (p < s_end) { @@ -1509,7 +1509,7 @@ nupa_subcktcall(dico_t *dico, const char *s, const char *x, jp = getexpress(NULL, &ustr, jp); } else { jp++; - if (*kp > ' ') + if ((unsigned char) (*kp) > ' ') message(dico, "Subckt call, symbol %c not understood\n", *kp); } diff --git a/src/frontend/parser/complete.c b/src/frontend/parser/complete.c index 794ae3b3a..7264167b9 100644 --- a/src/frontend/parser/complete.c +++ b/src/frontend/parser/complete.c @@ -91,7 +91,6 @@ cp_ccom(wordlist *wlist, char *buf, bool esc) int j, arg; buf = cp_unquote(copy(buf)); - cp_wstrip(buf); if (wlist) { /* Not the first word. */ cc = getccom(wlist->wl_word); if (cc && cc->cc_invalid) diff --git a/src/frontend/parser/lexical.c b/src/frontend/parser/lexical.c index cd970ea3a..ee961a1b2 100644 --- a/src/frontend/parser/lexical.c +++ b/src/frontend/parser/lexical.c @@ -200,13 +200,10 @@ nloop: if (c != EOF) numeofs = 0; - if (c != EOF) /* Don't need to do this really. */ - c = strip(c); - /* if '\' or '^', add following character to linebuf */ if ((c == '\\' && DIR_TERM != '\\') || (c == '\026') /* ^V */ ) { - c = quote(cp_readchar(&string, cp_inp_cur)); - push(&linebuf, strip(c)); + c = cp_readchar(&string, cp_inp_cur); + push(&linebuf, c); } /* if reading from fcn backeval() for backquote subst. */ @@ -265,7 +262,7 @@ nloop: { if ((c == '\n') || (c == EOF) || (c == ESCAPE)) goto gotchar; - push(&buf, quote(c)); + push(&buf, c); push(&linebuf, c); } push(&linebuf, '\''); @@ -285,7 +282,7 @@ nloop: if (c == '\\') { push(&linebuf, c); c = cp_readchar(&string, cp_inp_cur); - push(&buf, quote(c)); + push(&buf, c); push(&linebuf, c); } else { push(&buf, c); @@ -459,15 +456,15 @@ prompt(void) s = "-> "; while (*s) { - switch (strip(*s)) { + switch (*s) { case '!': fprintf(cp_out, "%d", cp_event); break; case '\\': if (s[1]) - (void) putc(strip(*++s), cp_out); + (void) putc((*++s), cp_out); default: - (void) putc(strip(*s), cp_out); + (void) putc((*s), cp_out); } s++; } diff --git a/src/frontend/plotting/Makefile.am b/src/frontend/plotting/Makefile.am index 055cb75d3..d641bd116 100644 --- a/src/frontend/plotting/Makefile.am +++ b/src/frontend/plotting/Makefile.am @@ -26,9 +26,8 @@ libplotting_la_SOURCES = \ if !NO_X libplotting_la_SOURCES += \ x11.c \ - x11.h \ - xgraph.c \ - xgraph.h + x11.h + endif AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include -I$(top_srcdir)/src/frontend @X_CFLAGS@ diff --git a/src/frontend/plotting/gnuplot.c b/src/frontend/plotting/gnuplot.c index 5a0ff5015..96a77fd5d 100644 --- a/src/frontend/plotting/gnuplot.c +++ b/src/frontend/plotting/gnuplot.c @@ -1,5 +1,4 @@ /********** - * From xgraph.c: * Copyright 1992 Regents of the University of California. All rights reserved. * Author: 1992 David A. Gates, U. C. Berkeley CAD Group * @@ -56,7 +55,7 @@ void ft_gnuplot(double *xlims, double *ylims, FILE *file, *file_data; struct dvec *v, *scale = NULL; double xval, yval, prev_xval, extrange; - int i, dir, numVecs, linewidth, err, terminal_type; + int i, dir, numVecs, linewidth, gridlinewidth, err, terminal_type; bool xlog, ylog, nogrid, markers; char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text, plotstyle[BSIZE_SP], terminal[BSIZE_SP]; @@ -108,9 +107,17 @@ void ft_gnuplot(double *xlims, double *ylims, } } + /* get linewidth for plotting the graph from .spiceinit */ if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) linewidth = 1; - if (linewidth < 1) linewidth = 1; + if (linewidth < 1) + linewidth = 1; + /* get linewidth for grid from .spiceinit */ + if (!cp_getvar("xgridwidth", CP_NUM, &gridlinewidth, 0)) + gridlinewidth = 1; + if (gridlinewidth < 1) + gridlinewidth = 1; + if (!cp_getvar("pointstyle", CP_STRING, pointstyle, sizeof(pointstyle))) { markers = FALSE; @@ -154,9 +161,16 @@ void ft_gnuplot(double *xlims, double *ylims, } /* Set up the file header. */ -#if !defined(__MINGW32__) && !defined(_MSC_VER) +#if !defined(__MINGW__) && !defined(_MSC_VER) && !defined(__CYGWIN__) fprintf(file, "set terminal X11 noenhanced\n"); +#elif defined(__CYGWIN__) +#ifndef EXT_ASC + fprintf(file, "set encoding utf8\n"); +#endif #else +#ifndef EXT_ASC + fprintf(file, "set encoding utf8\n"); +#endif fprintf(file, "set termoption noenhanced\n"); #endif if (title) { @@ -181,8 +195,8 @@ void ft_gnuplot(double *xlims, double *ylims, tfree(text); } if (!nogrid) { - if (linewidth > 1) - fprintf(file, "set grid lw %d \n" , linewidth); + if (gridlinewidth > 1) + fprintf(file, "set grid lw %d \n" , gridlinewidth); else fprintf(file, "set grid\n"); } @@ -216,8 +230,8 @@ void ft_gnuplot(double *xlims, double *ylims, fprintf(file, "#set ytics 1\n"); fprintf(file, "#set y2tics 1\n"); - if (linewidth > 1) - fprintf(file, "set border lw %d\n", linewidth); + if (gridlinewidth > 1) + fprintf(file, "set border lw %d\n", gridlinewidth); if (plottype == PLOT_COMB) { strcpy(plotstyle, "boxes"); @@ -305,7 +319,7 @@ void ft_gnuplot(double *xlims, double *ylims, (void) fclose(file); /* Write out the data and setup arrays */ - bool mono = (plottype == PLOT_MONOLIN); + bool mono = (plottype != PLOT_RETLIN); dir = 0; prev_xval = NAN; for (i = 0; i < scale->v_length; i++) { diff --git a/src/frontend/plotting/graf.c b/src/frontend/plotting/graf.c index 15ad1bdb8..6c427daeb 100644 --- a/src/frontend/plotting/graf.c +++ b/src/frontend/plotting/graf.c @@ -79,7 +79,8 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ const char *ylabel, /* Labels for axes. */ int xtype, int ytype, /* The types of the data graphed. */ const char *pname, - const char *commandline) /* For xi_zoomdata() */ + const char *commandline, /* For xi_zoomdata() */ + int prevgraph) /* plot id, if started from a previous plot*/ { GRAPH *graph; wordlist *wl; @@ -120,6 +121,10 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ } } + if (!cp_getvar("ticchar", CP_STRING, graph->ticchar, 1)) { + strcpy(graph->ticchar, "X"); + } + if (cp_getvar("ticlist", CP_LIST, ticlist, 0)) { wl = vareval("ticlist"); ticlist = wl_flatten(wl); @@ -150,6 +155,16 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ graph->plotname = tprintf("%s: %s", pname, plotname); + + /* restore background color from previous graph, e.g. for zooming, + it will be used in NewViewport(graph) */ + if (prevgraph > 0) { + graph->mgraphid = prevgraph; + } + else { + graph->mgraphid = 0; + } + /* note: have enum here or some better convention */ if (NewViewport(graph) == 1) { /* note: where is the error message generated? */ @@ -158,6 +173,19 @@ int gr_init(double *xlims, double *ylims, /* The size of the screen. */ return (FALSE); } + /* restore data from previous graph, e.g. for zooming */ + if (prevgraph > 0) { + int i; + GRAPH* pgraph = FindGraph(prevgraph); + /* transmit colors */ + for (i = 0; i < 25; i++) { + graph->colorarray[i] = pgraph->colorarray[i]; + } + strcpy(graph->ticchar, pgraph->ticchar); + graph->ticdata = pgraph->ticdata; + graph->ticmarks = pgraph->ticmarks; + } + /* layout decisions */ /* note: have to do before gr_fixgrid and after NewViewport */ graph->viewportxoff = graph->fontwidth * 8; /* 8 lines on left */ @@ -286,47 +314,37 @@ void gr_point(struct dvec *dv, return; } } - SetColor(dv->v_color); + SetColor(dv->v_color, currentgraph); switch (currentgraph->plottype) { double *tics; case PLOT_LIN: - case PLOT_MONOLIN: + case PLOT_RETLIN: /* If it's a linear plot, ignore first point since we don't want to connect with oldx and oldy. */ - if (np) { - DevDrawLine(fromx, fromy, tox, toy); - } + if (np) + DevDrawLine(fromx, fromy, tox, toy, FALSE); + if ((tics = currentgraph->ticdata) != NULL) { for (; *tics < HUGE; tics++) if (*tics == (double) np) { - DevDrawText("x", (int) (tox - currentgraph->fontwidth / 2), + DevDrawText(currentgraph->ticchar, (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2), 0); - /* gr_redraw will redraw this w/o our having to save it - Guenther Roehrich 22-Jan-99 */ - /* SaveText(currentgraph, "x", - (int) (tox - currentgraph->fontwidth / 2), - (int) (toy - currentgraph->fontheight / 2)); */ break; } } else if ((currentgraph->ticmarks >0) && (np > 0) && (np % currentgraph->ticmarks == 0)) { /* Draw an 'x' */ - DevDrawText("x", (int) (tox - currentgraph->fontwidth / 2), + DevDrawText(currentgraph->ticchar, (int) (tox - currentgraph->fontwidth / 2), (int) (toy - currentgraph->fontheight / 2), 0); - /* gr_redraw will redraw this w/o our having to save it - Guenther Roehrich 22-Jan-99 */ - /* SaveText(currentgraph, "x", - (int) (tox - currentgraph->fontwidth / 2), - (int) (toy - currentgraph->fontheight / 2)); */ } break; case PLOT_COMB: DatatoScreen(currentgraph, 0.0, currentgraph->datawindow.ymin, &dummy, &ymin); - DevDrawLine(tox, ymin, tox, toy); + DevDrawLine(tox, ymin, tox, toy, FALSE); break; case PLOT_POINT: /* Here, gi_linestyle is the character used for the point. */ @@ -403,35 +421,22 @@ static void gr_start_internal(struct dvec *dv, bool copyvec) currentgraph->plotdata = link; - /* Add the scale vector to the list of vectors associated with the plot + /* Copy the scale vector, add it to the vector as v_scale * and use the copy instead of the original scale vector if requested */ { struct dvec * const custom_scale = dv->v_scale; - if (custom_scale != (struct dvec *) NULL) { - link = TMALLOC(struct dveclist, 1); - link->next = currentgraph->plotdata; - + if (custom_scale != (struct dvec*) NULL) { if (copyvec) { - link->vector = vec_copy(dv->v_scale); - link->vector->v_flags |= VF_PERMANENT; - link->next->vector->v_scale = link->vector; - link->f_own_vector = TRUE; + currentgraph->plotdata->vector->v_scale = vec_copy(dv->v_scale); + currentgraph->plotdata->vector->v_scale->v_flags |= VF_PERMANENT; } - else { - link->vector = dv->v_scale; - link->f_own_vector = FALSE; - } - - /* Make the new vector the start of the list of vectors */ - currentgraph->plotdata = link; } } - /* Put the legend entry on the screen. */ - drawlegend(currentgraph, cur.plotno++, dv); -} /* end of function gr_start_internal */ - + if (!cp_getvar("nolegend", CP_BOOL, NULL, 0)) + drawlegend(currentgraph, cur.plotno++, dv); +} /* Start one plot of a graph */ @@ -469,7 +474,7 @@ void drawlegend(GRAPH *graph, int plotno, struct dvec *dv) const int y = graph->absolute.height - graph->fontheight - ((plotno + 2) / 2) * (graph->fontheight); const int i = y + graph->fontheight / 2 + 1; - SetColor(dv->v_color); + SetColor(dv->v_color, graph); if (graph->plottype == PLOT_POINT) { char buf[16]; (void) sprintf(buf, "%c : ", dv->v_linestyle); @@ -477,12 +482,12 @@ void drawlegend(GRAPH *graph, int plotno, struct dvec *dv) } else { SetLinestyle(dv->v_linestyle); - DevDrawLine(x, i, x_base, i); + DevDrawLine(x, i, x + graph->viewport.width / 20, i, FALSE); } - SetColor(1); - DevDrawText(dv->v_name, x_base + graph->fontwidth, y, 0); -} /* end of function drawlegend */ - + SetColor(1, graph); + DevDrawText(dv->v_name, x + graph->viewport.width / 20 + + graph->fontwidth, y, 0); +} /* end one plot of a graph */ @@ -605,7 +610,8 @@ void gr_redraw(GRAPH *graph) cur.plotno = 0; for (link = graph->plotdata; link; link = link->next) { /* redraw legend */ - drawlegend(graph, cur.plotno++, link->vector); + if (!cp_getvar("nolegend", CP_BOOL, NULL, 0)) + drawlegend(graph, cur.plotno++, link->vector); /* replot data if onevalue, pass it a NULL scale @@ -632,7 +638,7 @@ void gr_restoretext(GRAPH *graph) /* restore text */ for (k = graph->keyed; k; k = k->next) { - SetColor(k->colorindex); + SetColor(k->colorindex, graph); DevDrawText(k->text, k->x, k->y, 0); } } @@ -743,7 +749,7 @@ static int iplot(struct plot *pl, int id) (void) gr_init(xlims, ylims, xs->v_name, pl->pl_title, NULL, n_vec_plot, 0.0, 0.0, GRID_LIN, PLOT_LIN, xs->v_name, yl, xs->v_type, yt, - plot_cur->pl_typename, commandline); + plot_cur->pl_typename, commandline, 0); for (v = pl->pl_dvecs; v; v = v->v_next) { if (v->v_flags & VF_PLOT) { diff --git a/src/frontend/plotting/graf.h b/src/frontend/plotting/graf.h index 9d73c5cab..d960a3b14 100644 --- a/src/frontend/plotting/graf.h +++ b/src/frontend/plotting/graf.h @@ -19,7 +19,8 @@ int gr_init(double *xlims, double *ylims, const char *xlabel, const char *ylabel, /* Labels for axes. */ int xtype, int ytype, - const char *pname, const char *commandline); + const char *pname, const char *commandline, + int prevgraph); void gr_point(struct dvec *dv, double newx, double newy, double oldx, double oldy, int np); diff --git a/src/frontend/plotting/graphdb.c b/src/frontend/plotting/graphdb.c index 861721ecf..82656ea44 100644 --- a/src/frontend/plotting/graphdb.c +++ b/src/frontend/plotting/graphdb.c @@ -60,6 +60,7 @@ GRAPH *NewGraph(void) LISTGRAPH *list; const int BucketId = RunningId % NUMGBUCKETS; + /* allocate memory for graph via LISTGRAPH */ if ((list = TMALLOC(LISTGRAPH, 1)) == NULL) { internalerror("can't allocate a listgraph"); return (GRAPH *) NULL; @@ -258,6 +259,8 @@ int DestroyGraph(int id) nextd = d->next; if (d->f_own_vector) { /* list responsible for freeing this vector */ + if (d->vector->v_scale) + dvec_free(d->vector->v_scale); dvec_free(d->vector); } txfree(d); diff --git a/src/frontend/plotting/grid.c b/src/frontend/plotting/grid.c index 0c1b2f73b..468b42350 100644 --- a/src/frontend/plotting/grid.c +++ b/src/frontend/plotting/grid.c @@ -17,10 +17,30 @@ Modified: 2001 AlansFixes #include +#ifdef HAS_WINGUI +#undef BOOLEAN +#include +typedef struct { /* Extra window data */ + HWND wnd; /* window */ + HDC hDC; /* Device context of window */ + RECT Area; /* plot area */ + int ColorIndex; /* Index of actual color */ + int PaintFlag; /* 1 with WM_PAINT */ + int FirstFlag; /* 1 before first update */ +} tWindowData; +typedef tWindowData *tpWindowData; /* pointer to it */ +#endif + +#ifndef X_DISPLAY_MISSING +extern int X11_GetLenStr(GRAPH *gr, char* instring); +#endif + #define RAD_TO_DEG (180.0 / M_PI) +#define RELPOSXUNIT 0.6 /* old position of the UNIT label */ typedef enum { x_axis, y_axis } Axis; +static int unitshift; /* shift of unit label if x label is too large */ static double *lingrid(GRAPH *graph, double lo, double hi, double delta, int type, Axis axis); static double *loggrid(GRAPH *graph, double lo, double hi, int type, Axis axis); @@ -54,7 +74,7 @@ gr_fixgrid(GRAPH *graph, double xdelta, double ydelta, int xtype, int ytype) if (graph->grid.gridtype == GRID_NONE) graph->grid.gridtype = GRID_LIN; - SetColor(1); + SetColor(1, graph); SetLinestyle(1); if ((graph->data.xmin > graph->data.xmax) || @@ -105,18 +125,6 @@ gr_fixgrid(GRAPH *graph, double xdelta, double ydelta, int xtype, int ytype) graph->datawindow.xmin = dd[0]; graph->datawindow.xmax = dd[1]; - - /* do we really need this? */ - /* - SetLinestyle(0); - DevDrawLine(graph->viewportxoff, graph->viewportyoff, - graph->viewport.width + graph->viewportxoff, - graph->viewportyoff); - DevDrawLine(graph->viewportxoff, graph->viewportyoff, - graph->viewportxoff, - graph->viewport.height + graph->viewportyoff); - SetLinestyle(1); - */ } @@ -124,14 +132,85 @@ void gr_redrawgrid(GRAPH *graph) { - SetColor(1); + SetColor(1, graph); SetLinestyle(1); /* draw labels */ if (graph->grid.xlabel) { +#if defined(EXT_ASC) || (!defined HAS_WINGUI && defined X_DISPLAY_MISSING) DevDrawText(graph->grid.xlabel, - (int) (graph->absolute.width * 0.35), + (int)(graph->absolute.width * 0.35), + graph->fontheight, 0); +#else + if (eq(dispdev->name, "postscript")) + { + DevDrawText(graph->grid.xlabel, + (int)(graph->absolute.width * 0.35), + graph->fontheight, 0); + } + else { +#ifndef X_DISPLAY_MISSING + + /* x axis centered to graphics on X11 */ + /* utf-8: figure out the real length of the x label */ + int wlen = 0, i = 0; + while (graph->grid.xlabel[i]) { + if ((graph->grid.xlabel[i] & 0xc0) != 0x80) + wlen++; + i++; + } +#ifdef HAVE_LIBXFT + /* string lenth in pixels */ + int strsize = X11_GetLenStr(graph, graph->grid.xlabel); + DevDrawText(graph->grid.xlabel, + (int)((graph->absolute.width - strsize) / 2), graph->fontheight, 0); + + /* fix the position of the UNIT label */ + if (RELPOSXUNIT * graph->absolute.width < ((graph->absolute.width + strsize) / 2 + graph->fontwidth)) + unitshift = (int)((graph->absolute.width + strsize) / 2 + - RELPOSXUNIT * graph->absolute.width) + + graph->fontwidth; + else + unitshift = 0; /* reset for next plot window */ +#else + DevDrawText(graph->grid.xlabel, + (int) (graph->absolute.width * 0.35), graph->fontheight, + 0); + unitshift = 0; +#endif + } +#endif +#ifdef HAS_WINGUI + /* x axis centered to graphics on Windows */ + /* utf-8: figure out the real length of the x label */ + wchar_t *wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(graph->grid.xlabel) + 1); + int wlen = MultiByteToWideChar(CP_UTF8, 0, graph->grid.xlabel, -1, wtext, 2 * strlen(graph->grid.xlabel) + 1); + if (wlen == 0) { + fprintf(stderr, "UTF-8 to wide char conversion failed with 0x%x\n", GetLastError()); + fprintf(stderr, "%s could not be converted\n", graph->grid.xlabel); + } + else { + SIZE sz; + TEXTMETRICW tmw; + tpWindowData wd = graph->devdep; + GetTextMetricsW(wd->hDC, &tmw); + GetTextExtentPoint32W(wd->hDC, wtext, wlen, &sz); + DevDrawText(graph->grid.xlabel, + (int)((graph->absolute.width - sz.cx + tmw.tmOverhang) / 2), graph->fontheight, 0); + /* fix the position of the UNIT label */ + if (RELPOSXUNIT * graph->absolute.width < (graph->absolute.width + sz.cx + tmw.tmOverhang) / 2 + graph->fontwidth) + unitshift = (int)((graph->absolute.width + sz.cx + tmw.tmOverhang) / 2 + - RELPOSXUNIT * graph->absolute.width) + + graph->fontwidth; + else + unitshift = 0; /* reset for next plot window */ + } + } +#endif +#endif // EXT_ASC } + /* y axis: vertical text, centered to graph */ if (graph->grid.ylabel) { if (graph->grid.gridtype == GRID_POLAR || graph->grid.gridtype == GRID_SMITH || @@ -141,15 +220,59 @@ gr_redrawgrid(GRAPH *graph) graph->fontwidth, (graph->absolute.height * 3) / 4, 0); } else { - if (eq(dispdev->name, "postscript") || eq(dispdev->name, "Windows")) + + if (eq(dispdev->name, "postscript")) + DevDrawText(graph->grid.ylabel, + graph->fontwidth, + /*vertical text, midpoint in y is aligned midpoint of text string */ + (graph->absolute.height - strlen(graph->grid.ylabel) * graph->fontwidth) / 2, 90); +#ifdef EXT_ASC + else if (eq(dispdev->name, "Windows")) DevDrawText(graph->grid.ylabel, graph->fontwidth, /*vertical text, midpoint in y is aligned midpoint of text string */ - (graph->absolute.height - (int) strlen(graph->grid.ylabel) * graph->fontwidth) / 2, 90); - else /* FIXME: for now excluding X11 and others */ - DevDrawText(graph->grid.ylabel, + (graph->absolute.height - strlen(graph->grid.ylabel) * graph->fontwidth) / 2, 90); +#else +#ifdef HAS_WINGUI + /* Windows and UTF-8: check for string length (in pixels), + place vertical text centered in y with respect to grid */ + else if (eq(dispdev->name, "Windows")) { + /* utf-8: figure out the real length of the y label */ + wchar_t *wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(graph->grid.ylabel) + 1); + int wlen = MultiByteToWideChar(CP_UTF8, 0, graph->grid.ylabel, -1, wtext, 2 * strlen(graph->grid.ylabel) + 1); + if (wlen == 0) { + fprintf(stderr, "UTF-8 to wide char conversion failed with 0x%x\n", GetLastError()); + fprintf(stderr, "%s could not be converted\n", graph->grid.ylabel); + } + else { + SIZE sz; + TEXTMETRICW tmw; + tpWindowData wd = graph->devdep; + GetTextMetricsW(wd->hDC, &tmw); + GetTextExtentPoint32W(wd->hDC, wtext, wlen, &sz); +// printf("length: %d, deviation: %d\n", sz.cx, sz.cx - graph->fontwidth*wlen); + DevDrawText(graph->grid.ylabel, graph->fontwidth, - graph->absolute.height / 2, 90); + /*vertical text, midpoint in y is aligned midpoint of text string */ + (graph->absolute.height - (int)(1.2*sz.cx + tmw.tmOverhang)) / 2, 90); + } + } +#endif +#endif + else /* others */ + DevDrawText(graph->grid.ylabel, +#if !defined(X_DISPLAY_MISSING) && defined(HAVE_LIBXFT) + /* new x11 with xft and utf-8 + * calculate and add offsets in fcn X11_Text in X11.c + */ + 0, +#else + graph->fontwidth, +#endif + /*vertical text, y is midpoint of graph height */ + graph->absolute.height / 2, 90); + } } @@ -324,7 +447,7 @@ lingrid(GRAPH *graph, double lo, double hi, double delta, int type, Axis axis) graph->viewportxoff = (digits + 5 + mag - mag3) * graph->fontwidth; /* add height of the vertical text to offset*/ if (graph->grid.ylabel) - graph->viewportxoff += graph->fontheight; + graph->viewportxoff += (int)(1.6 * graph->fontheight); margin = graph->viewportyoff; /*max = graph->viewport.height + graph->viewportyoff;*/ max = graph->absolute.height - graph->viewportyoff; @@ -383,11 +506,10 @@ lingrid(GRAPH *graph, double lo, double hi, double delta, int type, Axis axis) buf[0] = '\0'; } - s = ft_typabbrev(type); - if (!s) - s = "Units"; - strncat(buf, s, sizeof(buf) - strlen(buf) - 1); - + if ((s = ft_typabbrev(type)) != NULL) + (void) strncat(buf, s, sizeof(buf) - strlen(buf) - 1); + else + (void) strncat(buf, "Units", sizeof(buf) - strlen(buf) - 1); if (delta == 0.0) { int i; double step; @@ -535,12 +657,12 @@ drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double if (axis == x_axis) DevDrawLine(graph->viewportxoff + i, graph->viewportyoff, graph->viewportxoff + i, - graph->viewport.height + graph->viewportyoff); + graph->viewport.height + graph->viewportyoff, TRUE); else DevDrawLine(graph->viewportxoff, graph->viewportyoff + i, graph->viewport.width + graph->viewportxoff, - graph->viewportyoff + i); + graph->viewportyoff + i, TRUE); } if (j == 0) SetLinestyle(1); @@ -552,7 +674,7 @@ drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double ((int) strlen(buf) * graph->fontwidth) / 2, (int) (graph->fontheight * 2.5), 0); else - DevDrawText(buf, graph->viewportxoff - + DevDrawText(buf, graph->viewportxoff - 2 - graph->fontwidth * (int) strlen(buf), graph->viewportyoff + i - graph->fontheight / 2, 0); @@ -562,8 +684,7 @@ drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double j += 1000; } if (axis == x_axis) - DevDrawText(units, (int) (graph->absolute.width * 0.6), - graph->fontheight, 0); + DevDrawText(units, (int) (graph->absolute.width * RELPOSXUNIT + unitshift), graph->fontheight, 0); else DevDrawText(units, graph->fontwidth, (int) (graph->absolute.height - 2 * graph->fontheight), 0); @@ -698,13 +819,15 @@ drawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, in graph->viewportyoff, graph->viewportxoff + i, graph->viewport.height - +graph->viewportyoff); + +graph->viewportyoff, + TRUE); else DevDrawLine(graph->viewportxoff, graph->viewportyoff + i, graph->viewport.width + graph->viewportxoff, - graph->viewportyoff + i); + graph->viewportyoff + i, + TRUE); } if (j == -2) @@ -745,13 +868,15 @@ drawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, in graph->viewportyoff, graph->viewportxoff + m, graph->viewport.height - + graph->viewportyoff); + + graph->viewportyoff, + TRUE); else DevDrawLine(graph->viewportxoff, graph->viewportyoff + m, graph->viewport.width + graph->viewportxoff, - graph->viewportyoff + m); + graph->viewportyoff + m, + TRUE); } } SetLinestyle(0); @@ -759,7 +884,7 @@ drawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, in } if (axis == x_axis) - DevDrawText(units, (int) (graph->absolute.width * 0.6), + DevDrawText(units, (int) (graph->absolute.width * RELPOSXUNIT + unitshift), graph->fontheight, 0); else DevDrawText(units, graph->fontwidth, @@ -938,7 +1063,7 @@ drawpolargrid(GRAPH *graph) graph->grid.yaxis.circular.center, graph->grid.xaxis.circular.radius)) { - DevDrawLine(x1, y1, x2, y2); + DevDrawLine(x1, y1, x2, y2, TRUE); /* Add a label here */ /*XXXX*/ adddeglabel(graph, i * 30, x2, y2, x1, y1, @@ -974,7 +1099,7 @@ drawpolargrid(GRAPH *graph) graph->grid.xaxis.circular.center, graph->grid.yaxis.circular.center, graph->grid.xaxis.circular.radius)) { - DevDrawLine(x1, y1, x2, y2); + DevDrawLine(x1, y1, x2, y2, TRUE); /* Put on the label */ adddeglabel(graph, i, x2, y2, x1, y1, graph->grid.xaxis.circular.center, @@ -1313,7 +1438,7 @@ drawsmithgrid(GRAPH *graph) if (zheight < 0) zheight = - zheight; DevDrawLine(gr_xcenter - zheight, gr_ycenter + yoff, - gr_xcenter + zheight, gr_ycenter + yoff); + gr_xcenter + zheight, gr_ycenter + yoff, TRUE); DevDrawText("0", gr_xcenter + zheight + gi_fntwidth, gr_ycenter + yoff - gi_fntheight / 2, 0); DevDrawText("o", gr_xcenter + zheight + gi_fntwidth * 2, gr_ycenter + yoff, 0); @@ -1352,7 +1477,7 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d /* Let's be lazy and just draw everything -- we won't get called too * much and the circles get clipped anyway... */ - SetColor(18); + SetColor(18, graph); cliparc((double) (centx + xoffset + radoff - rad), (double) (centy + yoffset), rad, 2*angle, @@ -1366,7 +1491,7 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d M_PI - 2 * angle, centx, centy, maxrad, 0); /* Draw the upper and lower circles. */ - SetColor(19); + SetColor(19, graph); aclip = cliparc((double) (centx + xoffset + radoff), (double) (centy + yoffset + irad), irad, (double) (M_PI * 1.5 + 2 * iangle), @@ -1375,7 +1500,7 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d xlab = (int)(centx + xoffset + radoff + irad * cos(aclip)); ylab = (int)(centy + yoffset + irad * (1 + sin(aclip))); if ((ylab - gr_ycenter) > graph->fontheight) { - SetColor(1); + SetColor(1, graph); adddeglabel(graph, pdeg, xlab, ylab, gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); /* @@ -1383,7 +1508,7 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d adddeglabel(graph, ndeg, xlab, ylab, gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); */ - SetColor(19); + SetColor(19, graph); } } aclip = cliparc((double) (centx + xoffset + radoff), @@ -1394,14 +1519,14 @@ arcset(GRAPH *graph, double rad, double prevrad, double irad, double iprevrad, d if ((aclip >= 0 && aclip < 2*M_PI - M_PI/180) && (pdeg < 359)) { xlab = (int)(centx + xoffset + radoff + irad * cos(aclip)); ylab = (int)(centy + yoffset + irad * (sin(aclip) - 1)); - SetColor(1); + SetColor(1, graph); adddeglabel(graph, ndeg, xlab, ylab, gr_xcenter, gr_ycenter, gr_xcenter, gr_ycenter); - SetColor(19); + SetColor(19, graph); } /* Now toss the labels on... */ - SetColor(1); + SetColor(1, graph); x = centx + xoffset + (int)radoff - 2 * (int)rad - gi_fntwidth * (int) strlen(plab) - 2; diff --git a/src/frontend/plotting/plot5.c b/src/frontend/plotting/plot5.c index 5c4db679c..155a089bb 100644 --- a/src/frontend/plotting/plot5.c +++ b/src/frontend/plotting/plot5.c @@ -108,8 +108,11 @@ int Plt5_Clear(void) } -int Plt5_DrawLine(int x1, int y1, int x2, int y2) +int +Plt5_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { + NG_IGNORE(isgrid); + putc('l', plotfile); putsi(x1); putsi(y1); @@ -207,9 +210,11 @@ int Plt5_SetLinestyle(int linestyleid) /* ARGSUSED */ -int Plt5_SetColor(int colorid) + +int Plt5_SetColor(int colorid, GRAPH *graph) { NG_IGNORE(colorid); + NG_IGNORE(graph); /* do nothing */ return 0; diff --git a/src/frontend/plotting/plotcurv.c b/src/frontend/plotting/plotcurv.c index 768e9560d..da7026adb 100644 --- a/src/frontend/plotting/plotcurv.c +++ b/src/frontend/plotting/plotcurv.c @@ -130,7 +130,7 @@ ft_graf(struct dvec *v, struct dvec *xs, bool nostart) * interpolation. */ if ((degree == 1) && (gridsize == 0)) { - bool mono = (currentgraph->plottype == PLOT_MONOLIN); + bool mono = (currentgraph->plottype != PLOT_RETLIN); dir = 0; for (i = 0, j = v->v_length; i < j; i++) { dx = isreal(xs) ? xs->v_realdata[i] : diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index db54545eb..5ded37c6e 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -13,7 +13,6 @@ #include "plotit.h" #include "points.h" #include "agraf.h" -#include "xgraph.h" #include "gnuplot.h" #include "graf.h" @@ -283,6 +282,9 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) return FALSE; } + static double *xprevgraph = NULL; + int prevgraph = 0; + static bool nointerp = FALSE; static GRIDTYPE gtype = GRID_LIN; static PLOTTYPE ptype = PLOT_LIN; @@ -295,7 +297,6 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) int i, y_type, xt; wordlist *wwl; char *nxlabel = NULL, *nylabel = NULL, *ntitle = NULL; - double tstep, tstart, tstop, ttime; /* Save start of vectors on entry for cleaning up junk left behind @@ -333,6 +334,8 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) nxlabel = getword(wwl, "xlabel"); nylabel = getword(wwl, "ylabel"); ntitle = getword(wwl, "title"); + /* remove sgraphid */ + txfree(getlims(wwl, "sgraphid", 1)); /* Build the plot command. This construction had been done with wordlists * and reversing, and flattening, but it is clearer as well as much more @@ -437,6 +440,13 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) txfree(getlims(wl, "ydel", 1)); } + if (!sameflag || !xprevgraph) { + xprevgraph = getlims(wl, "sgraphid", 1); + if(xprevgraph) + prevgraph = (int)(*xprevgraph); + } else { + txfree(getlims(wl, "sgraphid", 1)); + } /* Get the grid type and the point type. Note we can't do if-else * here because we want to catch all the grid types. */ @@ -600,14 +610,14 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) pfound = TRUE; } } - if (getflag(wl, "noretraceplot")) { + if (getflag(wl, "retraceplot")) { if (pfound) { fprintf(cp_err, "Warning: too many plot types given. " - "\"noretraceplot\" is ignored.\n"); + "\"retraceplot\" is ignored.\n"); } else { - ptype = PLOT_MONOLIN; + ptype = PLOT_RETLIN; pfound = TRUE; } } @@ -640,8 +650,8 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) if (eq(buf, "linplot")) { ptype = PLOT_LIN; } - else if (eq(buf, "noretraceplot")) { - ptype = PLOT_MONOLIN; + else if (eq(buf, "retraceplot")) { + ptype = PLOT_RETLIN; } else if (eq(buf, "combplot")) { ptype = PLOT_COMB; @@ -1072,19 +1082,6 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) y_type = d ? SV_NOTYPE : vecs->v_type; -#ifndef X_DISPLAY_MISSING - if (devname && eq(devname, "xgraph")) { - /* Interface to XGraph-11 Plot Program */ - ft_xgraph(xlims, ylims, hcopy, - title ? title : vecs->v_plot->pl_title, - xlabel ? xlabel : ft_typabbrev(vecs->v_scale->v_type), - ylabel ? ylabel : ft_typabbrev(y_type), - gtype, ptype, vecs); - rtn = TRUE; - goto quit; - } -#endif - if (devname && eq(devname, "gnuplot")) { /* Interface to Gnuplot Plot Program */ ft_gnuplot(xlims, ylims, hcopy, @@ -1133,7 +1130,7 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) xdelta ? *xdelta : 0.0, ydelta ? *ydelta : 0.0, gtype, ptype, xlabel, ylabel, xt, y_type, - plot_cur->pl_typename, ds_get_buf(&ds_cline))) { + plot_cur->pl_typename, ds_get_buf(&ds_cline), prevgraph)) { goto quit; } diff --git a/src/frontend/plotting/x11.c b/src/frontend/plotting/x11.c index f581028f5..8a88ce270 100644 --- a/src/frontend/plotting/x11.c +++ b/src/frontend/plotting/x11.c @@ -14,6 +14,7 @@ Author: 1988 Jeffrey M. Hsu # include # include /* PN */ # include /* PN */ +# include # include "ngspice/graph.h" # include "ngspice/ftedbgra.h" @@ -37,6 +38,10 @@ Author: 1988 Jeffrey M. Hsu # include # include +#ifdef HAVE_LIBXFT +#include +#endif + # ifdef DEBUG # include /* for _Xdebug */ # endif @@ -62,10 +67,23 @@ typedef struct x11info { int isopen; Widget shell, form, view, buttonbox, buttons[2]; XFontStruct *font; - GC gc; + GC gc; /* graphics context for graphs */ + GC gridgc; /* graphics context for grid, linewidth may differ */ int lastx, lasty; /* used in X_DrawLine */ int lastlinestyle; /* used in X_DrawLine */ Pixel colors[NUMCOLORS]; + char txtcolor[16]; + char bgcolor[16]; + char fname[BSIZE_SP]; + int fsize; + /* use with xft */ +#ifdef HAVE_LIBXFT + XftFont *font0; + XftFont *font90; + XftDraw* draw; + XftColor color; + Colormap cmap; +#endif } X11devdep; #define DEVDEP(g) (*((X11devdep *) (g)->devdep)) @@ -91,6 +109,8 @@ static Bool noclear = False; static GRAPH *lasthardcopy; /* graph user selected */ static int X11_Open = 0; static int numdispplanes; +static int xfont_size; +static char fontname[513]; /* static functions */ static void initlinestyles(void); @@ -99,7 +119,10 @@ static void X_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *fy); static void linear_arc(int x0, int y0, int radius, double theta, double delta_theta); static void slopelocation(GRAPH *graph, int x0, int y0); static void zoomin(GRAPH *graph); - +#ifdef HAVE_LIBXFT +static int Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* name, int fsize); +static int X11_DefineXft(GRAPH *graph); +#endif //XtEventHandler static void handlekeypressed(Widget w, XtPointer clientdata, XEvent *ev, Boolean *continue_dispatch); static void handlebuttonev(Widget w, XtPointer graph, XEvent *ev, Boolean *continue_dispatch); @@ -128,7 +151,6 @@ X11_Init(void) XGCValues gcvalues; - /* grrr, Xtk forced contortions */ char *argv[2]; int argc = 2; @@ -149,20 +171,16 @@ X11_Init(void) argv[2] = "-geometry"; argv[3] = "=1x1+2+2"; */ - + /* initialze internationalization (i18n) */ + XtSetLanguageProc(NULL, NULL, NULL); /* initialize X toolkit */ toplevel = XtInitialize("ngspice", "Nutmeg", NULL, 0, &argc, argv); + setlocale(LC_NUMERIC, "C"); display = XtDisplay(toplevel); X11_Open = 1; - /* "invert" works better than "xor" for B&W */ - - /* xor gc should be a function of the pixels that are written on */ - /* gcvalues.function = GXxor; */ - /* this patch makes lines visible on true color displays - Guenther Roehrich 22-Jan-99 */ gcvalues.function = GXinvert; gcvalues.line_width = 1; gcvalues.foreground = 1; @@ -200,10 +218,15 @@ initlinestyles(void) } +/* initialize color selection for grid/text, background and graphs. + Input is by setting the variables color0 (background), color1 + (grid/text) and color%id with %id from2 to 19. color%id may be set + to color name string or rgb:0/FF/F0 rgb:0/F/0 rgbd:295/0/128 */ static void initcolors(GRAPH *graph) { int i; + bool gridgiven = TRUE; static char *colornames[] = { "black", /* white */ "white", "red", "blue", "orange", "green", "pink", @@ -214,18 +237,18 @@ initcolors(GRAPH *graph) "yellow", "" }; - XColor visualcolor, exactcolor; + XColor visualcolor, exactcolor, bgcolor; char buf[BSIZE_SP], colorstring[BSIZE_SP]; int xmaxcolors = NUMCOLORS; /* note: can we get rid of this? */ if (numdispplanes == 1) { /* black and white */ xmaxcolors = 2; - DEVDEP(graph).colors[0] = DEVDEP(graph).view->core.background_pixel; - if (DEVDEP(graph).colors[0] == WhitePixel(display, DefaultScreen(display))) - DEVDEP(graph).colors[1] = BlackPixel(display, DefaultScreen(display)); + graph->colorarray[0] = DEVDEP(graph).view->core.background_pixel; + if (graph->colorarray[0] == WhitePixel(display, DefaultScreen(display))) + graph->colorarray[1] = BlackPixel(display, DefaultScreen(display)); else - DEVDEP(graph).colors[1] = WhitePixel(display, DefaultScreen(display)); + graph->colorarray[1] = WhitePixel(display, DefaultScreen(display)); } else { if (numdispplanes < NXPLANES) @@ -233,38 +256,80 @@ initcolors(GRAPH *graph) for (i = 0; i < xmaxcolors; i++) { (void) sprintf(buf, "color%d", i); - if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) + if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { (void) strcpy(colorstring, colornames[i]); + if(i == 1) + gridgiven = FALSE; + } + /* colorstring by integer numbers between 0 and 255 */ + else if (ciprefix("rgbd:", colorstring)) { + char *t1, *t2, *t3, *tmpstr; + tmpstr = colorstring + 5; + if (tmpstr) { + t1 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t2 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t3 = copy(tmpstr); + if (t1 && t2 && t3) { + double c1, c2, c3; + c1 = strtol(t1, NULL, 10) / 255.; + c2 = strtol(t2, NULL, 10) / 255.; + c3 = strtol(t3, NULL, 10) / 255.; + c1 = fmax(0., fmin(c1, 1.)); + c2 = fmax(0., fmin(c2, 1.)); + c3 = fmax(0., fmin(c3, 1.)); + tfree(t1); + tfree(t2); + tfree(t3); + sprintf(colorstring, "RGBi:%.3f/%.3f/%.3f", c1, c2, c3); + } + else { + fprintf(cp_err, "Error: Could not evaluate color%d", i); + continue; + } + } + } + if (!XAllocNamedColor(display, DefaultColormap(display, DefaultScreen(display)), colorstring, &visualcolor, &exactcolor)) { (void) sprintf(ErrorMessage, "can't get color %s\n", colorstring); externalerror(ErrorMessage); - DEVDEP(graph).colors[i] = i ? BlackPixel(display, + graph->colorarray[i] = i ? BlackPixel(display, DefaultScreen(display)) : WhitePixel(display, DefaultScreen(display)); continue; } - DEVDEP(graph).colors[i] = visualcolor.pixel; - - /* MW. I don't need this, everyone must know what he is doing - if (i > 0 && - DEVDEP(graph).colors[i] == DEVDEP(graph).view->core.background_pixel) { - DEVDEP(graph).colors[i] = DEVDEP(graph).colors[0]; - } */ - + if (i == 0) { + bgcolor = visualcolor; + strncpy(DEVDEP(graph).bgcolor, colorstring, 15); + } + if ((!gridgiven) && (i == 1)) { + /* select grid color according to background color. + Empirical selection using the color depth of the background */ + /* switch the grid and text color depending on background */ + int tcolor = (int)bgcolor.red + (int)(1.5 * bgcolor.green) + (int)bgcolor.blue; + if (tcolor > 92160) { + graph->colorarray[1] = BlackPixel(display, DefaultScreen(display)); + strncpy(DEVDEP(graph).txtcolor, "black", 15); + } + else { + graph->colorarray[1] = WhitePixel(display, DefaultScreen(display)); + strncpy(DEVDEP(graph).txtcolor, "white", 15); + } + } + else { + graph->colorarray[i] = visualcolor.pixel; + if (i == 1) + strncpy(DEVDEP(graph).txtcolor, colorstring, 15); + } } - /* MW. Set Beackgroound here */ - XSetWindowBackground(display, DEVDEP(graph).window, DEVDEP(graph).colors[0]); - - /* if (DEVDEP(graph).colors[0] != DEVDEP(graph).view->core.background_pixel) { - DEVDEP(graph).colors[0] = DEVDEP(graph).view->core.background_pixel; - } */ } for (i = xmaxcolors; i < NUMCOLORS; i++) { - DEVDEP(graph).colors[i] = DEVDEP(graph).colors[i + 1 - xmaxcolors]; + graph->colorarray[i] = graph->colorarray[i + 1 - xmaxcolors]; } } @@ -286,7 +351,7 @@ handlekeypressed(Widget w, XtPointer client_data, XEvent *ev, Boolean *continue_ /* write it */ PushGraphContext(graph); text[nbytes] = '\0'; - SetColor(1); + SetColor(1, graph); DevDrawText(text, keyev->x, graph->absolute.height - keyev->y, 0); /* save it */ SaveText(graph, text, keyev->x, graph->absolute.height - keyev->y); @@ -348,11 +413,13 @@ handle_wm_messages(Widget w, XtPointer client_data, XEvent *ev, Boolean *cont) int X11_NewViewport(GRAPH *graph) { - char fontname[513]; /* who knows . . . */ +// char fontname[513]; /* who knows . . . */ char *p, *q; Cursor cursor; XSetWindowAttributes w_attrs; XGCValues gcvalues; + XGCValues gridgcvalues; + GRAPH *pgraph = NULL; static Arg formargs[ ] = { { XtNleft, (XtArgVal) XtChainLeft }, @@ -376,8 +443,8 @@ X11_NewViewport(GRAPH *graph) }; static Arg viewargs[] = { { XtNresizable, (XtArgVal) TRUE }, - { XtNwidth, (XtArgVal) 300 }, - { XtNheight, (XtArgVal) 300 }, + { XtNwidth, (XtArgVal) 600 }, + { XtNheight, (XtArgVal) 500 }, { XtNright, (XtArgVal) XtChainRight } }; int trys; @@ -389,6 +456,7 @@ X11_NewViewport(GRAPH *graph) DEVDEP(graph).shell = XtCreateApplicationShell ("shell", topLevelShellWidgetClass, NULL, 0); + XtVaSetValues(DEVDEP(graph).shell, XtNtitleEncoding, XInternAtom(display, "UTF8_STRING", False), NULL); XtVaSetValues(DEVDEP(graph).shell, XtNtitle, graph->plotname, NULL); /* set up form widget */ @@ -428,7 +496,9 @@ X11_NewViewport(GRAPH *graph) /* set up fonts */ if (!cp_getvar("xfont", CP_STRING, fontname, sizeof(fontname))) (void) strcpy(fontname, DEF_FONT); + strncpy(DEVDEP(graph).fname, fontname, BSIZE_SP - 1); +#ifndef HAVE_LIBXFT for (p = fontname; *p && *p <= ' '; p++) ; @@ -437,7 +507,6 @@ X11_NewViewport(GRAPH *graph) ; *q = '\0'; } - trys = 1; while (!(DEVDEP(graph).font = XLoadQueryFont(display, fontname))) { sprintf(ErrorMessage, "can't open font %s", fontname); @@ -449,11 +518,30 @@ X11_NewViewport(GRAPH *graph) } trys += 1; } +#endif + /* font size */ + if (!cp_getvar("xfont_size", CP_NUM, &xfont_size, 0)) + xfont_size = 16; + +#ifndef HAVE_LIBXFT graph->fontwidth = DEVDEP(graph).font->max_bounds.rbearing - DEVDEP(graph).font->min_bounds.lbearing + 1; graph->fontheight = DEVDEP(graph).font->max_bounds.ascent + DEVDEP(graph).font->max_bounds.descent + 1; +#else + int wl, wh; + int ret = Xget_str_length("ABCD", &wl, &wh, NULL, fontname, xfont_size); + if (ret == 1) + ret = Xget_str_length("我能吞下", &wl, &wh, NULL, fontname, xfont_size); + if (ret == 1) { + fprintf(cp_err, "Error: Could not establish a font for %s\n", fontname); + return 1; + } + graph->fontwidth = (int)(wl / 4); + graph->fontheight = wh; + DEVDEP(graph).fsize = xfont_size; +#endif XtRealizeWidget(DEVDEP(graph).shell); @@ -462,14 +550,50 @@ X11_NewViewport(GRAPH *graph) w_attrs.bit_gravity = ForgetGravity; XChangeWindowAttributes(display, DEVDEP(graph).window, CWBitGravity, &w_attrs); - /* have to note font and set mask GCFont in XCreateGC, p.w.h. */ - gcvalues.font = DEVDEP(graph).font->fid; - gcvalues.line_width = MW_LINEWIDTH; - gcvalues.cap_style = CapNotLast; - gcvalues.function = GXcopy; - DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, - GCFont | GCLineWidth | GCCapStyle | GCFunction, &gcvalues); + int linewidth, gridlinewidth; + /* If we had a previous graph, e.g. after zooming, we + have to set the background color already here, because + background is set below */ + if (graph->mgraphid > 0) { + pgraph = FindGraph(graph->mgraphid); + } + /* get linewidth information from .spiceinit or .control section */ + if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) + linewidth = MW_LINEWIDTH; + if (linewidth < 0) + linewidth = MW_LINEWIDTH; + if (pgraph) + gcvalues.line_width = graph->graphwidth = pgraph->graphwidth; + else + gcvalues.line_width = graph->graphwidth = linewidth; + + /* get linewidth information from .spiceinit or .control section */ + if (!cp_getvar("xgridwidth", CP_NUM, &gridlinewidth, 0)) + gridlinewidth = MW_LINEWIDTH; + if (gridlinewidth < 0) + gridlinewidth = MW_LINEWIDTH; + + if (pgraph) + gridgcvalues.line_width = graph->gridwidth = pgraph->gridwidth; + else + gridgcvalues.line_width = graph->gridwidth = gridlinewidth; + + gridgcvalues.cap_style = gcvalues.cap_style = CapNotLast; + gridgcvalues.function = gcvalues.function = GXcopy; +#ifndef HAVE_LIBXFT + gridgcvalues.font = gcvalues.font = DEVDEP(graph).font->fid; + DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, + GCFont | GCLineWidth | GCCapStyle | GCFunction, &gcvalues); + DEVDEP(graph).gridgc = XCreateGC(display, DEVDEP(graph).window, + GCFont | GCLineWidth | GCCapStyle | GCFunction, &gridgcvalues); +#else + DEVDEP(graph).gc = XCreateGC(display, DEVDEP(graph).window, + GCLineWidth | GCCapStyle | GCFunction, &gcvalues); + DEVDEP(graph).gridgc = XCreateGC(display, DEVDEP(graph).window, + GCLineWidth | GCCapStyle | GCFunction, &gridgcvalues); + +#endif /* should absolute.positions really be shell.pos? */ graph->absolute.xpos = DEVDEP(graph).view->core.x; graph->absolute.ypos = DEVDEP(graph).view->core.y; @@ -479,10 +603,23 @@ X11_NewViewport(GRAPH *graph) initlinestyles(); initcolors(graph); + /* we have a 'mother' graph and want to get its colors */ + int i; + if(pgraph) { + for(i = 0; i < 25; i++) + graph->colorarray[i] = pgraph->colorarray[i]; + } + + XSetWindowBackground(display, DEVDEP(graph).window, graph->colorarray[0]); + /* set up cursor */ cursor = XCreateFontCursor(display, XC_left_ptr); XDefineCursor(display, DEVDEP(graph).window, cursor); + #ifdef HAVE_LIBXFT + X11_DefineXft(graph); +#endif + /* WM_DELETE_WINDOW protocol */ atom_wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False); atom_wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False); @@ -513,14 +650,21 @@ X11_Close(void) int -X11_DrawLine(int x1, int y1, int x2, int y2) +X11_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { if (DEVDEP(currentgraph).isopen) - XDrawLine(display, DEVDEP(currentgraph).window, + if (isgrid) { + XDrawLine(display, DEVDEP(currentgraph).window, + DEVDEP(currentgraph).gridgc, + x1, currentgraph->absolute.height - y1, + x2, currentgraph->absolute.height - y2); + } + else { + XDrawLine(display, DEVDEP(currentgraph).window, DEVDEP(currentgraph).gc, x1, currentgraph->absolute.height - y1, x2, currentgraph->absolute.height - y2); - + } return 0; } @@ -554,19 +698,90 @@ X11_Text(char *text, int x, int y, int angle) { /* We specify text position by lower left corner, so have to adjust for X11's font nonsense. */ - NG_IGNORE(angle); - if (DEVDEP(currentgraph).isopen) - XDrawString(display, DEVDEP(currentgraph).window, - DEVDEP(currentgraph).gc, x, - currentgraph->absolute.height - - (y + DEVDEP(currentgraph).font->max_bounds.descent), - text, (int) strlen(text)); + int wlen = 0, wheight = 0; - /* note: unlike before, we do not save any text here */ +#ifndef HAVE_LIBXFT + if (DEVDEP(currentgraph).isopen) + XDrawString(display, DEVDEP(currentgraph).window, + DEVDEP(currentgraph).gc, x, + currentgraph->absolute.height + - (y + DEVDEP(currentgraph).font->max_bounds.descent), + text, (int) strlen(text)); + + /* note: unlike before, we do not save any text here */ +#else + /* Draw text */ + if(angle == 0) { + XftDrawStringUtf8( + DEVDEP(currentgraph).draw, &DEVDEP(currentgraph).color, DEVDEP(currentgraph).font0, + x, currentgraph->absolute.height - y, (FcChar8*)text, strlen(text)); + } + else if (angle == 90) { + int wlen, wheight; + /* calculate and add offset, if ylabel with angle 90° */ + Xget_str_length(text, &wlen, &wheight, DEVDEP(currentgraph).font90, NULL, 0); + + XftDrawStringUtf8( + DEVDEP(currentgraph).draw, &DEVDEP(currentgraph).color, DEVDEP(currentgraph).font90, + x + (int)(1.5 * wlen), currentgraph->absolute.height - y + (int)(0.5 * wheight), (FcChar8*)text, strlen(text)); + } + else + fprintf(stderr, " Xft: angles other than 0 or 90 are not supported in ngspice\n"); + +#endif return 0; } +#ifdef HAVE_LIBXFT +int X11_DefineXft(GRAPH *graph) +{ +/* font selection with rotation */ + XftPattern *new_pat = XftPatternCreate(); // the pattern we will use for rotating + XftPatternAddString(new_pat, XFT_FAMILY, DEVDEP(graph).fname); + XftPatternAddDouble (new_pat, XFT_PIXEL_SIZE, (double)DEVDEP(graph).fsize); + + + XftResult rot_result; + XftPattern *rot_pat = XftFontMatch(display, 0, new_pat, &rot_result); /* do not destroy!*/ + DEVDEP(graph).font0 = XftFontOpenPattern(display, rot_pat); + + if(DEVDEP(graph).font0 == NULL) { + fprintf(stderr, "Can't load font pattern %s\n", DEVDEP(graph).fname); + } + + /* for angle 90 deg */ + XftMatrix m; + XftMatrixInit(&m); + int angle = 90; + XftMatrixRotate(&m,cos(M_PI*angle/180.),sin(M_PI*angle/180.)); + XftPatternAddMatrix (new_pat, XFT_MATRIX,&m); + + XftPattern *rot_pat2 = XftFontMatch(display, 0, new_pat, &rot_result); /* do not destroy!*/ + DEVDEP(graph).font90 = XftFontOpenPattern(display, rot_pat2); + + XftPatternDestroy(new_pat); + + Colormap cmap = DefaultColormap(display, 0); + XftColor color; + XRenderColor rcolor; + XColor xxcolor; + /* pixel -> XColor -> XftColor */ + xxcolor.pixel = graph->colorarray[1]; + XQueryColor(display, cmap, &xxcolor); + rcolor.alpha = 65535; + rcolor.red = xxcolor.red; + rcolor.green = xxcolor.green; + rcolor.blue = xxcolor.blue; + XftColorAllocValue(display, DefaultVisual(display, 0), cmap, &rcolor, &color); + DEVDEP(graph).color = color; + DEVDEP(graph).cmap = cmap; + DEVDEP(graph).draw = XftDrawCreate( + display, DEVDEP(graph).window, DefaultVisual(display, 0), cmap + ); + return 0; +} +#endif int X11_DefineColor(int colorid, double red, double green, double blue) @@ -608,11 +823,14 @@ X11_SetLinestyle(int linestyleid) } XChangeGC(display, DEVDEP(currentgraph).gc, GCLineStyle, &values); - + XChangeGC(display, DEVDEP(currentgraph).gridgc, GCLineStyle, &values); currentgraph->linestyle = linestyleid; XSetDashes(display, DEVDEP(currentgraph).gc, 0, xlinestyles[linestyleid], 4); + + XSetDashes(display, DEVDEP(currentgraph).gridgc, 0, + xlinestyles[linestyleid], 4); } return 0; @@ -620,11 +838,13 @@ X11_SetLinestyle(int linestyleid) int -X11_SetColor(int colorid) +X11_SetColor(int colorid, GRAPH *graph) { currentgraph->currentcolor = colorid; XSetForeground(display, DEVDEP(currentgraph).gc, - DEVDEP(currentgraph).colors[colorid]); + currentgraph->colorarray[colorid]); + XSetForeground(display, DEVDEP(currentgraph).gridgc, + currentgraph->colorarray[colorid]); return 0; } @@ -825,11 +1045,12 @@ zoomin(GRAPH *graph) if (!eq(plot_cur->pl_typename, buf2)) { (void) sprintf(buf, - "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e; setplot $curplot\n", - buf2, graph->commandline, fx0, fx1, fy0, fy1); + "setplot %s; %s xlimit %.20e %.20e ylimit %.20e %.20e sgraphid %d; setplot $curplot\n", + buf2, graph->commandline, fx0, fx1, fy0, fy1, graph->graphid); } else { - (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e\n", - graph->commandline, fx0, fx1, fy0, fy1); + /* set the foreground and background colors to the "calling" window's colors */ + (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e sgraphid %d\n", + graph->commandline, fx0, fx1, fy0, fy1, graph->graphid); } /* don't use the following if using GNU Readline or BSD EditLine */ @@ -906,8 +1127,17 @@ void RemoveWindow(GRAPH *graph) /* MW. Not sure but DestroyGraph might free() too much - try Xt...() first */ XtUnmapWidget(DEVDEP(graph).shell); XtDestroyWidget(DEVDEP(graph).shell); +#ifndef HAVE_LIBXFT XFreeFont(display, DEVDEP(graph).font); +#endif XFreeGC(display, DEVDEP(graph).gc); + XFreeGC(display, DEVDEP(graph).gridgc); +#ifdef HAVE_LIBXFT + XftFontClose( display, DEVDEP(graph).font0); + XftFontClose( display, DEVDEP(graph).font90); + XftDrawDestroy(DEVDEP(graph).draw); + XftColorFree(display, DefaultVisual(display, 0), DEVDEP(graph).cmap, &DEVDEP(graph).color); +#endif } if (graph == currentgraph) @@ -1101,10 +1331,51 @@ linear_arc(int x0, int y0, int radius, double theta, double delta_theta) y1 = y2; x2 = x0 + (int)(radius * cos(theta + i*dphi)); y2 = y0 + (int)(radius * sin(theta + i*dphi)); - X11_DrawLine(x1, y1, x2, y2); + X11_DrawLine(x1, y1, x2, y2, FALSE); } } +#ifdef HAVE_LIBXFT + /* After font selection for XftTextExtentsUtf8 + * to measure character string length. + * Same as rotation below, but 0° angle */ +static int +Xget_str_length(char *text, int* wlen, int* wheight, XftFont* gfont, char* foname, int fsize) { + XGlyphInfo extents; + XftFont* hfont = NULL; + /* if font name and font size are given */ + if (gfont == NULL) { + XftPattern *ext_pat = XftPatternCreate(); // the pattern we will use for rotating + XftPatternAddString(ext_pat, XFT_FAMILY, foname); + XftPatternAddDouble(ext_pat, XFT_PIXEL_SIZE, (double)fsize); + XftResult ext_result; + XftPattern *font_pat = XftFontMatch(display, 0, ext_pat, &ext_result); + hfont = gfont = XftFontOpenPattern(display, font_pat); + XftPatternDestroy(ext_pat); + } + if(gfont) + XftTextExtentsUtf8( display, gfont, (XftChar8 *)text, strlen(text), &extents ); + else { + return 1; + } + if(hfont) + XftFontClose( display,hfont); + + /* size of the string */ + *wlen = extents.width; + *wheight = extents.height; + return 0; +} + +/* get the length of an utf-8 string in pixels */ +int +X11_GetLenStr(GRAPH *gr, char* instring) +{ + int wl, wh; + Xget_str_length(instring, &wl, &wh, NULL, DEVDEP(gr).fname, DEVDEP(gr).fsize); + return wl; +} +#endif #else diff --git a/src/frontend/plotting/xgraph.c b/src/frontend/plotting/xgraph.c deleted file mode 100644 index ff40075bd..000000000 --- a/src/frontend/plotting/xgraph.c +++ /dev/null @@ -1,167 +0,0 @@ -/********** -Copyright 1992 Regents of the University of California. All rights reserved. -Author: 1992 David A. Gates, U. C. Berkeley CAD Group -**********/ - -/* - * Xgraph-11 plots. - */ - -#include "ngspice/ngspice.h" -#include "ngspice/cpdefs.h" -#include "ngspice/ftedefs.h" -#include "ngspice/dvec.h" -#include "ngspice/fteparse.h" -#include "xgraph.h" - - -#define XG_MAXVECTORS 64 - -void -ft_xgraph(double *xlims, double *ylims, char *filename, char *title, char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, struct dvec *vecs) -{ - FILE *file; - struct dvec *v, *scale; - double xval, yval; - int i, numVecs, linewidth; - bool xlog, ylog, nogrid, markers; - char buf[BSIZE_SP], pointstyle[BSIZE_SP], *text; - - /* Sanity checking. */ - for (v = vecs, numVecs = 0; v; v = v->v_link2) - numVecs++; - - if (numVecs == 0) { - return; - } else if (numVecs > XG_MAXVECTORS) { - fprintf(cp_err, "Error: too many vectors for Xgraph.\n"); - return; - } - - if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) - linewidth = 1; - - if (linewidth < 1) - linewidth = 1; - - if (!cp_getvar("pointstyle", CP_STRING, pointstyle, sizeof(pointstyle))) { - markers = FALSE; - } else { - if (cieq(pointstyle, "markers")) - markers = TRUE; - else - markers = FALSE; - } - - /* Make sure the gridtype is supported. */ - switch (gridtype) { - case GRID_LIN: - nogrid = xlog = ylog = FALSE; - break; - case GRID_XLOG: - xlog = TRUE; - nogrid = ylog = FALSE; - break; - case GRID_YLOG: - ylog = TRUE; - nogrid = xlog = FALSE; - break; - case GRID_LOGLOG: - xlog = ylog = TRUE; - nogrid = FALSE; - break; - case GRID_NONE: - nogrid = TRUE; - xlog = ylog = FALSE; - break; - default: - fprintf(cp_err, "Error: grid type unsupported by Xgraph.\n"); - return; - } - - /* Open the output file. */ - if ((file = fopen(filename, "w")) == NULL) { - perror(filename); - return; - } - - /* Set up the file header. */ - if (title) { - text = cp_unquote(title); - fprintf(file, "TitleText: %s\n", text); - tfree(text); - } - if (xlabel) { - text = cp_unquote(xlabel); - fprintf(file, "XUnitText: %s\n", text); - tfree(text); - } - if (ylabel) { - text = cp_unquote(ylabel); - fprintf(file, "YUnitText: %s\n", text); - tfree(text); - } - if (nogrid) { - fprintf(file, "Ticks: True\n"); - } - - if (xlog) { - fprintf(file, "LogX: True\n"); - if (xlims) { - fprintf(file, "XLowLimit: % e\n", log10(xlims[0])); - fprintf(file, "XHighLimit: % e\n", log10(xlims[1])); - } - } else { - if (xlims) { - fprintf(file, "XLowLimit: % e\n", xlims[0]); - fprintf(file, "XHighLimit: % e\n", xlims[1]); - } - } - - if (ylog) { - fprintf(file, "LogY: True\n"); - if (ylims) { - fprintf(file, "YLowLimit: % e\n", log10(ylims[0])); - fprintf(file, "YHighLimit: % e\n", log10(ylims[1])); - } - } else { - if (ylims) { - fprintf(file, "YLowLimit: % e\n", ylims[0]); - fprintf(file, "YHighLimit: % e\n", ylims[1]); - } - } - - fprintf(file, "LineWidth: %d\n", linewidth); - fprintf(file, "BoundBox: True\n"); - - if (plottype == PLOT_COMB) { - fprintf(file, "BarGraph: True\n"); - fprintf(file, "NoLines: True\n"); - } else if (plottype == PLOT_POINT) { - if (markers) - fprintf(file, "Markers: True\n"); - else - fprintf(file, "LargePixels: True\n"); - fprintf(file, "NoLines: True\n"); - } - - /* Write out the data. */ - for (v = vecs; v; v = v->v_link2) { - scale = v->v_scale; - if (v->v_name) - fprintf(file, "\"%s\"\n", v->v_name); - - for (i = 0; i < scale->v_length; i++) { - xval = isreal(scale) ? - scale->v_realdata[i] : realpart(scale->v_compdata[i]); - yval = isreal(v) ? - v->v_realdata[i] : realpart(v->v_compdata[i]); - fprintf(file, "% e % e\n", xval, yval); - } - fprintf(file, "\n"); - } - - (void) fclose(file); - (void) sprintf(buf, "xgraph %s &", filename); - (void) system(buf); -} diff --git a/src/frontend/plotting/xgraph.h b/src/frontend/plotting/xgraph.h deleted file mode 100644 index e900bfa54..000000000 --- a/src/frontend/plotting/xgraph.h +++ /dev/null @@ -1,13 +0,0 @@ -/************* - * Header file for xgraph.c - * 1999 E. Rouat - ************/ - -#ifndef ngspice_XGRAPH_H -#define ngspice_XGRAPH_H - -void ft_xgraph(double *xlims, double *ylims, char *filename, char *title, - char *xlabel, char *ylabel, GRIDTYPE gridtype, PLOTTYPE plottype, - struct dvec *vecs); - -#endif diff --git a/src/frontend/postcoms.c b/src/frontend/postcoms.c index 0484fcd4a..0f628424c 100644 --- a/src/frontend/postcoms.c +++ b/src/frontend/postcoms.c @@ -19,7 +19,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "completion.h" #include "postcoms.h" -#include "quote.h" #include "variable.h" #include "parser/complete.h" /* va: throwaway */ #include "plotting/plotting.h" diff --git a/src/frontend/postsc.c b/src/frontend/postsc.c index 857f71e68..aa6b55c98 100644 --- a/src/frontend/postsc.c +++ b/src/frontend/postsc.c @@ -40,6 +40,36 @@ Author: 1988 Jeffrey M. Hsu #define FONTWIDTH 6 /* printer default fontwidth */ #define FONTHEIGHT 14 /* printer default fontheight */ + +typedef struct { + int red, green, blue; +} COLOR; + +/* duplicated colors from src/frontend/plotting/x11.c in rgb-style */ +static const COLOR colors[] = {{ 0, 0, 0}, /*0: black */ + {255, 255, 255}, /*1: white */ + {255, 0, 0}, /*2: red */ + { 0, 0, 255}, /*3: blue */ + {255, 165, 0}, /*4: orange */ + { 0, 255, 0}, /*5: green */ + {255, 192, 203}, /*6: pink */ + {165, 42, 42}, /*7: brown */ + {240, 230, 140}, /*8: khaki */ + {221, 160, 221}, /*9: plum */ + {218, 112, 214}, /*10: orchid */ + {238, 130, 238}, /*11: violet */ + {176, 48, 96}, /*12: maroon */ + { 64, 224, 208}, /*13: turqoise */ + {160, 82, 45}, /*14: sienna */ + {255, 127, 80}, /*15: coral */ + { 0, 255, 255}, /*16: cyan */ + {255, 0, 255}, /*17: magenta */ + {255, 215, 0}, /*18: gold */ + {255, 255, 0}, /*19: yello */ + { 96, 96, 96}, /*20: gray for smith grid */ + {150, 150, 150}, /*21: gray for smith grid */ + {128, 128, 128}}; /*22: gray for normal grid */ + typedef struct { int lastlinestyle, lastcolor; /* initial invalid value */ int lastx, lasty, linecount; @@ -66,16 +96,19 @@ static int fontheight = FONTHEIGHT; static int screenflag = 0; static int colorflag = 0; static int setbgcolor = 0; -static int settxcolor = -1; +static int settxcolor = 1; static double scale; /* Used for fine tuning */ static int xtadj; /* text adjustment x */ static int ytadj; /* text adjustment y */ static int hcopygraphid; - +static double linewidth; +static double gridlinewidth; +static int maxcolor = 2; void PS_LinestyleColor(int linestyleid, int colorid); void PS_SelectColor(int colorid); void PS_Stroke(void); +size_t utf8_to_latin9(char *const output, const char *const input, const size_t length); /* Set scale, color and size of the plot */ @@ -83,6 +116,8 @@ int PS_Init(void) { char pswidth[30], psheight[30]; + maxcolor = NUMELEMS(colors); + if (!cp_getvar("hcopyscale", CP_STRING, psscale, sizeof(psscale))) { scale = 1.0; } else { @@ -98,12 +133,26 @@ int PS_Init(void) dispdev->numcolors = 2; } else { - /* get backgroung color and set plot to color */ + /* get text color and set plot to color */ colorflag = 1; - dispdev->numcolors = 21; /* don't know what the maximum should be */ + dispdev->numcolors = maxcolor; cp_getvar("hcopypstxcolor", CP_NUM, &settxcolor, 0); } + if (settxcolor > maxcolor || settxcolor < 0) { + fprintf(stderr, "Bad PS text color selection %d\n", settxcolor); + fprintf(stderr, " Maximum for hcopypstxcolor is %d\n\n", maxcolor - 1); + colorflag = 0; + dispdev->numcolors = 2; + } + + if (setbgcolor > maxcolor || setbgcolor < 0) { + fprintf(stderr, "Bad PS background color selection %d\n", setbgcolor); + fprintf(stderr, " Maximum for hcopypscolor is %d\n", maxcolor - 1); + fprintf(stderr, " Set to 1 (white)\n\n"); + setbgcolor = 1; + } + /* plot size */ if (!cp_getvar("hcopywidth", CP_STRING, pswidth, sizeof( pswidth))) { dispdev->width = (int)(7.75 * 72.0 * scale); /* (8 1/2 - 3/4) * 72 */ @@ -126,6 +175,19 @@ int PS_Init(void) dispdev->height = 10000; } + /* get linewidth information from spinit */ + if (!cp_getvar("xbrushwidth", CP_REAL, &linewidth, 0)) + linewidth = 0; + if (linewidth < 0) + linewidth = 0; + + /* get linewidth for grid from spinit */ + if (!cp_getvar("xgridwidth", CP_REAL, &gridlinewidth, 0)) + gridlinewidth = linewidth; + if (gridlinewidth < 0) + gridlinewidth = 0; + + /* The following side effects have to be considered * when the printer is called by com_hardcopy ! * gr_init: @@ -148,7 +210,7 @@ int PS_Init(void) } else { sscanf(psfontsize, "%d", &fontsize); - if ((fontsize < 10) || (fontsize > 14)) + if ((fontsize < 10) || (fontsize > 18)) fontsize = 10; fontwidth = (int)(0.5 + 0.6 * fontsize); fontheight = (int)(2.5 + 1.2 * fontsize); @@ -170,6 +232,7 @@ int PS_NewViewport(GRAPH *graph) { int x1, x2, y1, y2; hcopygraphid = graph->graphid; + /* devdep initially contains name of output file */ if ((plotfile = fopen((char*)graph->devdep, "w")) == NULL) { perror((char *) graph->devdep); @@ -198,13 +261,13 @@ int PS_NewViewport(GRAPH *graph) xoff = (int)(scale * XOFF); yoff = (int)(scale * YOFF); - x1 = (int)(0.75 * 72); + x1 = (int) (0.5 * 72 - fontheight); y1 = x1; - x2 = (int)(graph->absolute.width + .75 * 72); + x2 = (int)(graph->absolute.width + .5 * 72); y2 = (int)(graph->absolute.height + .75 * 72); /* start file off with a % */ fprintf(plotfile, "%%!PS-Adobe-3.0 EPSF-3.0\n"); - fprintf(plotfile, "%%%%Creator: nutmeg\n"); + fprintf(plotfile, "%%%%Creator: ngspice\n"); fprintf(plotfile, "%%%%BoundingBox: %d %d %d %d\n", x1, y1, x2, y2); /* Re-encoding to allow 'extended asccii' @@ -221,7 +284,6 @@ int PS_NewViewport(GRAPH *graph) fprintf(plotfile, " definefont\n"); fprintf(plotfile, "} def\n"); fprintf(plotfile, "/%s /%sLatin1 ISOLatin1Encoding Re-encode\n", psfont, psfont); - fprintf(plotfile, "%g %g scale\n", 1.0 / scale, 1.0 / scale); if (colorflag == 1) { /* set the background to color given in spinit (or 0) */ @@ -233,10 +295,10 @@ int PS_NewViewport(GRAPH *graph) fprintf(plotfile, "closepath fill\n"); } + /* set up a reasonable font */ fprintf(plotfile, "/%sLatin1 findfont %d scalefont setfont\n\n", psfont, (int) (fontsize * scale)); - graph->devdep = TMALLOC(PSdevdep, 1); graph->n_byte_devdep = sizeof(PSdevdep); DEVDEP(graph).lastlinestyle = -1; @@ -265,7 +327,8 @@ int PS_Close(void) * and reset currentgraph to graphid 1, if possible */ if (!screenflag) { - DestroyGraph(hcopygraphid); + if (hcopygraphid > 0) + DestroyGraph(hcopygraphid); currentgraph = FindGraph(1); } return 0; @@ -279,7 +342,8 @@ int PS_Clear(void) } -int PS_DrawLine(int x1, int y1, int x2, int y2) +int +PS_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { /* note: this is not extendible to more than one graph => will have to give NewViewport a writeable graph XXX */ @@ -298,6 +362,10 @@ int PS_DrawLine(int x1, int y1, int x2, int y2) if (x1 != x2 || y1 != y2) { fprintf(plotfile, "%d %d lineto\n", x2 + xoff, y2 + yoff); DEVDEP(currentgraph).linecount += 1; + if(isgrid) + fprintf(plotfile, "%f setlinewidth\n", gridlinewidth); + else + fprintf(plotfile, "%f setlinewidth\n", linewidth); } DEVDEP(currentgraph).lastx = x2; @@ -331,6 +399,9 @@ int PS_Text(char *text, int x, int y, int angle) { int savedlstyle, savedcolor; +#ifndef EXT_ASC + utf8_to_latin9(text, text, strlen(text)); +#endif /* set linestyle to solid or may get funny color text on some plotters */ savedlstyle = currentgraph->linestyle; @@ -339,12 +410,12 @@ int PS_Text(char *text, int x, int y, int angle) PS_SetLinestyle(SOLID); /* set text color to black if background is not white */ if (setbgcolor > 0) - PS_SetColor(0); + PS_SetColor(0, currentgraph); else - PS_SetColor(1); + PS_SetColor(1, currentgraph); /* if color is given by set hcopytxpscolor=settxcolor, give it a try */ if (settxcolor >= 0) - PS_SetColor(settxcolor); + PS_SetColor(settxcolor, currentgraph); /* stroke the path if there's an open one */ PS_Stroke(); /* move to (x, y) */ @@ -360,7 +431,7 @@ int PS_Text(char *text, int x, int y, int angle) /* restore old linestyle */ - PS_SetColor(savedcolor); + PS_SetColor(savedcolor, currentgraph); PS_SetLinestyle(savedlstyle); return 0; } @@ -387,8 +458,9 @@ int PS_SetLinestyle(int linestyleid) } -int PS_SetColor(int colorid) +int PS_SetColor(int colorid, GRAPH *graph) { + NG_IGNORE(graph); PS_LinestyleColor(currentgraph->linestyle, colorid); return 0; } @@ -409,31 +481,6 @@ void PS_SelectColor(int colorid) /* should be replaced by PS_DefineCol char rgb[30], s_red[30] = "0x", s_green[30] = "0x", s_blue[30] = "0x"; int red = 0, green = 0, blue = 0, maxval = 1; int i; - typedef struct { int red, green, blue;} COLOR; - /* duplicated colors from src/frontend/plotting/x11.c in rgb-style */ - const COLOR colors[] = {{ 0, 0, 0}, /*0: black */ - {255, 255, 255}, /*1: white */ - {255, 0, 0}, /*2: red */ - { 0, 0, 255}, /*3: blue */ - {255, 165, 0}, /*4: orange */ - { 0, 255, 0}, /*5: green */ - {255, 192, 203}, /*6: pink */ - {165, 42, 42}, /*7: brown */ - {240, 230, 140}, /*8: khaki */ - {221, 160, 221}, /*9: plum */ - {218, 112, 214}, /*10: orchid */ - {238, 130, 238}, /*11: violet */ - {176, 48, 96}, /*12: maroon */ - { 64, 224, 208}, /*13: turqoise */ - {160, 82, 45}, /*14: sienna */ - {255, 127, 80}, /*15: coral */ - { 0, 255, 255}, /*16: cyan */ - {255, 0, 255}, /*17: magenta */ - /*{255, 215, 0}, 18: gold */ - { 96, 96, 96}, /*18: gray for smith grid */ - /*{255, 255, 0}, 19: yello */ - {150, 150, 150}, /*19: gray for smith grid */ - {128, 128, 128}}; /*20: gray for normal grid */ /* Extract the rgbcolor, format is: "rgb://" */ sprintf(colorN, "color%d", colorid); @@ -455,7 +502,7 @@ void PS_SelectColor(int colorid) /* should be replaced by PS_DefineCol strcpy(pscolor, colorstring); } } - if (colorid < 0 || colorid > 20) { + if (colorid < 0 || colorid >= maxcolor) { internalerror("bad colorid inside PS_SelectColor"); } else if (maxval == 1) { /* colorN is not an rgbstring, use default color */ sprintf(colorstring, "%1.3f %1.3f %1.3f", colors[colorid].red/255.0, @@ -523,3 +570,139 @@ void PS_Stroke(void) DEVDEP(currentgraph).linecount = 0; } } + +/* UTF-8 to ISO-8859-1/ISO-8859-15 mapper. +* Return 0..255 for valid ISO-8859-15 code points, 256 otherwise. +*/ +static inline unsigned int to_latin9(const unsigned int code) +{ + /* Code points 0 to U+00FF are the same in both. */ + if (code < 256U) + return code; + switch (code) { + case 0x0152U: return 188U; /* U+0152 = 0xBC: OE ligature */ + case 0x0153U: return 189U; /* U+0153 = 0xBD: oe ligature */ + case 0x0160U: return 166U; /* U+0160 = 0xA6: S with caron */ + case 0x0161U: return 168U; /* U+0161 = 0xA8: s with caron */ + case 0x0178U: return 190U; /* U+0178 = 0xBE: Y with diaresis */ + case 0x017DU: return 180U; /* U+017D = 0xB4: Z with caron */ + case 0x017EU: return 184U; /* U+017E = 0xB8: z with caron */ + case 0x20ACU: return 164U; /* U+20AC = 0xA4: Euro */ + default: return 256U; + } +} + +/* Convert an UTF-8 string to ISO-8859-15. +* All invalid sequences are ignored. +* Note: output == input is allowed, +* but input < output < input + length +* is not. +* Output has to have room for (length+1) chars, including the trailing NUL byte. +from http://stackoverflow.com/questions/11156473/is-there-a-way-to-convert-from-utf8-to-iso-8859-1#11173493 +*/ +size_t utf8_to_latin9(char *const output, const char *const input, const size_t length) +{ + unsigned char *out = (unsigned char *)output; + const unsigned char *in = (const unsigned char *)input; + const unsigned char *const end = (const unsigned char *)input + length; + unsigned int c; + + while (in < end) + if (*in < 128) + *(out++) = *(in++); /* Valid codepoint */ + else + if (*in < 192) + in++; /* 10000000 .. 10111111 are invalid */ + else + if (*in < 224) { /* 110xxxxx 10xxxxxx */ + if (in + 1 >= end) + break; + if ((in[1] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x1FU)) << 6U) + | ((unsigned int)(in[1] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 2; + + } + else + if (*in < 240) { /* 1110xxxx 10xxxxxx 10xxxxxx */ + if (in + 2 >= end) + break; + if ((in[1] & 192U) == 128U && + (in[2] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x0FU)) << 12U) + | (((unsigned int)(in[1] & 0x3FU)) << 6U) + | ((unsigned int)(in[2] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 3; + + } + else + if (*in < 248) { /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (in + 3 >= end) + break; + if ((in[1] & 192U) == 128U && + (in[2] & 192U) == 128U && + (in[3] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x07U)) << 18U) + | (((unsigned int)(in[1] & 0x3FU)) << 12U) + | (((unsigned int)(in[2] & 0x3FU)) << 6U) + | ((unsigned int)(in[3] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 4; + + } + else + if (*in < 252) { /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (in + 4 >= end) + break; + if ((in[1] & 192U) == 128U && + (in[2] & 192U) == 128U && + (in[3] & 192U) == 128U && + (in[4] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x03U)) << 24U) + | (((unsigned int)(in[1] & 0x3FU)) << 18U) + | (((unsigned int)(in[2] & 0x3FU)) << 12U) + | (((unsigned int)(in[3] & 0x3FU)) << 6U) + | ((unsigned int)(in[4] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 5; + + } + else + if (*in < 254) { /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (in + 5 >= end) + break; + if ((in[1] & 192U) == 128U && + (in[2] & 192U) == 128U && + (in[3] & 192U) == 128U && + (in[4] & 192U) == 128U && + (in[5] & 192U) == 128U) { + c = to_latin9((((unsigned int)(in[0] & 0x01U)) << 30U) + | (((unsigned int)(in[1] & 0x3FU)) << 24U) + | (((unsigned int)(in[2] & 0x3FU)) << 18U) + | (((unsigned int)(in[3] & 0x3FU)) << 12U) + | (((unsigned int)(in[4] & 0x3FU)) << 6U) + | ((unsigned int)(in[5] & 0x3FU))); + if (c < 256) + *(out++) = (unsigned char)c; + } + in += 6; + + } + else + in++; /* 11111110 and 11111111 are invalid */ + + /* Terminate the output string. */ + *out = '\0'; + + return (size_t)(out - (unsigned char *)output); +} diff --git a/src/frontend/quote.c b/src/frontend/quote.c index 3403d1e96..ffa9ff58c 100644 --- a/src/frontend/quote.c +++ b/src/frontend/quote.c @@ -3,52 +3,14 @@ Copyright 1990 Regents of the University of California. All rights reserved. Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group **********/ -/* - * - * Various things for quoting words. If this is not ascii, quote and - * strip are no-ops, so '' and \ quoting won't work. To fix this, sell - * your IBM machine and buy a vax. - */ #include #include "ngspice/ngspice.h" #include "ngspice/cpdefs.h" -#include "quote.h" -/* Strip all the 8th bits from a string (destructively). */ - -void -cp_wstrip(char *str) -{ - char c, d; - - if (str) - while ((c = *str) != '\0') { /* assign and test */ - d = (char) strip(c); - if (c != d) - *str = d; - str++; - } -} - - -/* Quote all characters in a word. */ - -void -cp_quoteword(char *str) -{ - if (str) - while (*str) { - *str = (char) quote(*str); - str++; - } -} - - -/* Print a word (strip the word first). */ - +/* Print a word */ void cp_printword(char *string, FILE *fp) { @@ -56,23 +18,10 @@ cp_printword(char *string, FILE *fp) if (string) for (s = string; *s; s++) - (void) putc((strip(*s)), fp); + (void) putc((*s), fp); } -/* (Destructively) strip all the words in a wlist. */ - -void -cp_striplist(wordlist *wlist) -{ - wordlist *wl; - - for (wl = wlist; wl; wl = wl->wl_next) - cp_wstrip(wl->wl_word); -} - - - /* Create a copy of the input string removing the enclosing quotes, * if they are present */ char * diff --git a/src/frontend/resource.c b/src/frontend/resource.c index 608b7ee44..37d07b6c1 100644 --- a/src/frontend/resource.c +++ b/src/frontend/resource.c @@ -16,7 +16,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "ngspice/ftedefs.h" #include "circuits.h" -#include "quote.h" #include "resource.h" #include "variable.h" #include "ngspice/cktdefs.h" diff --git a/src/frontend/variable.c b/src/frontend/variable.c index 5883b4c0a..a1027f192 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -15,7 +15,6 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group #include "circuits.h" #include "com_history.h" -#include "quote.h" #include "ngspice/cpextern.h" #include "variable.h" @@ -728,13 +727,12 @@ cp_getvar(char *name, enum cp_types type, void *retval, size_t rsize) break; case CP_STRING: { /* Gotta be careful to have room. */ char *s = cp_unquote(v->va_string); - cp_wstrip(s); - if (strlen(s) >= rsize - 1) { - fprintf(stderr, "Internal Error: string length for variable %s is limited to %zu chars\n", v->va_name, rsize); - controlled_exit(EXIT_BAD); + if (strlen(s) > rsize) { + fprintf(stderr, "Warning: string length for variable %s is limited to %zu chars\n", v->va_name, rsize); + /* limit the string length */ + s[rsize] = '\0'; } - else - strcpy((char*) retval, s); + strcpy((char*) retval, s); tfree(s); break; } @@ -902,7 +900,6 @@ wordlist *vareval(/* NOT const */ char *string) /* usage of vfree: variable v has to be freed only if created by cp_enqvar()! */ - cp_wstrip(string); if ((s = strchr(string, '[')) != NULL) { *s = '\0'; range = s + 1; diff --git a/src/frontend/wdisp/Makefile.am b/src/frontend/wdisp/Makefile.am index 423164907..8a0f5e640 100644 --- a/src/frontend/wdisp/Makefile.am +++ b/src/frontend/wdisp/Makefile.am @@ -7,6 +7,7 @@ libwindisp_la_SOURCES = \ windisp.h \ winprint.c \ winprint.h \ + wincolor.c \ ftegraf.h diff --git a/src/frontend/wdisp/wincolor.c b/src/frontend/wdisp/wincolor.c new file mode 100644 index 000000000..de53318cf --- /dev/null +++ b/src/frontend/wdisp/wincolor.c @@ -0,0 +1,223 @@ +/* Copyright: Holger Vogt, 2020 */ +/* Three Clause BSD */ +/* Universal color table and retrival */ + + +#include "ngspice/ngspice.h" + +#ifdef HAS_WINGUI + +#include "ngspice/cpextern.h" +#include "ngspice/hash.h" +#include "ngspice/macros.h" +#undef BOOLEAN +#include +#include "ngspice/wincolornames.h" +#include "ngspice/graph.h" + + + +static NGHASHPTR color_p; /* color hash table */ +static COLORREF get_wincolor(char* name, int nocolor); + +void wincolor_init_hash(COLORREF *ColorTable, int noc) +{ + int i; + char buf[BSIZE_SP], colorstring[BSIZE_SP]; + int nocolor = NUMELEMS(ctable); + color_p = nghash_init(nocolor); + nghash_unique(color_p, FALSE); + for (i = 0; i < nocolor; i++) { + strtolower(ctable[i].name); + ctable[i].rgbc = RGB(ctable[i].R, ctable[i].G, ctable[i].B); + nghash_insert(color_p, ctable[i].name, &(ctable[i].rgbc)); + } + + for (i = 0; i < noc; i++) { + (void) sprintf(buf, "color%d", i); + if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) + (void) strcpy(colorstring, stdcolornames[i]); + COLORREF* val = (COLORREF*)nghash_find(color_p, colorstring); + if(val) + ColorTable[i] = *val; + else + ColorTable[i] = 0; + } +} +/* evaluate rgb:0/FF/F0 rgb:0/F/0 rgbd:295/0/128 */ +static COLORREF get_wincolor_rgb(char *costr) +{ + char *tmpstr; + if (ciprefix("rgb:", costr)) { + char *t1, *t2, *t3; + tmpstr = costr + 4; + if (tmpstr) { + t1 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t2 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t3 = copy(tmpstr); + if (t1 && t2 && t3) { + int c1, c2, c3; + c1 = (int) strtol(t1, NULL, 16); + c2 = (int) strtol(t2, NULL, 16); + c3 = (int) strtol(t3, NULL, 16); + tfree(t1); + tfree(t2); + tfree(t3); + return RGB(c1, c2, c3); + } + } + + } + else if (ciprefix("rgbd:", costr)) { + char *t1, *t2, *t3; + tmpstr = costr + 5; + if (tmpstr) { + t1 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t2 = gettok_char(&tmpstr, '/', FALSE, FALSE); + tmpstr++; + t3 = copy(tmpstr); + if (t1 && t2 && t3) { + int c1, c2, c3; + c1 = (int) strtol(t1, NULL, 10); + c2 = (int) strtol(t2, NULL, 10); + c3 = (int) strtol(t3, NULL, 10); + tfree(t1); + tfree(t2); + tfree(t3); + return RGB(c1, c2, c3); + } + } + } + + fprintf(stderr, "Error: Cannot detect color in string %s, setting Web Green\n", costr); + return RGB(0, 128, 0); +} + +/* ColorTable[0]: background, ColorTable[1]: grid, text */ +void wincolor_init(COLORREF* ColorTable, int noc) +{ + int i; + static bool bgisblack = TRUE; + char buf[BSIZE_SP], colorstring[BSIZE_SP]; + int nocolor = NUMELEMS(ctable); + + for (i = 0; i < nocolor; i++) { + strtolower(ctable[i].name); + ctable[i].rgbc = RGB(ctable[i].R, ctable[i].G, ctable[i].B); + } + i = 0; + while(i < noc) { + /* when color0 is set to white and color1 is not given, set ColorTable[2] to black */ + (void)sprintf(buf, "color%d", i); + if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { + if (i == 1) { + /* switch the grid and text color depending on background */ + int tcolor = GetRValue(ColorTable[0]) + + (int)(1.5 * GetGValue(ColorTable[0])) + GetBValue(ColorTable[0]); + if (tcolor > 360) { + ColorTable[1] = RGB(0, 0, 0); + i++; + bgisblack = FALSE; + continue; + } + else { + ColorTable[1] = RGB(255, 255, 255); + i++; + bgisblack = TRUE; + continue; + } + } + /* old code: beginning with 12 the colors are repeated */ + else if (!bgisblack && (i == 12)) + (void)strcpy(colorstring, "black"); + else + (void)strcpy(colorstring, stdcolornames[i]); + } + else if (ciprefix("rgb", colorstring)){ + ColorTable[i] = get_wincolor_rgb(colorstring); + i++; + continue; + } + ColorTable[i] = get_wincolor(colorstring, nocolor); + i++; + } +} + +void wincolor_graph(COLORREF* ColorTable, int noc, GRAPH *graph) +{ + int i; + for (i = 0; i < noc; i++) { + graph->colorarray[i] = ColorTable[i]; + } +} + +void wincolor_redo(COLORREF* ColorTable, int noc) +{ + int i = 0; + static bool bgisblack = TRUE; + char buf[BSIZE_SP], colorstring[BSIZE_SP]; + int nocolor = NUMELEMS(ctable); + + while (i < noc) { + /* when color0 is set to white and color1 is not given, set text and grid color + as ColorTable[1] to black, when color0 is any other color, select black or + white text and grid color according to a weighted value derived from color0. + This selection is a compromise based on visibility.*/ + (void)sprintf(buf, "color%d", i); + if (!cp_getvar(buf, CP_STRING, colorstring, sizeof(colorstring))) { + if (i == 1) { + /* switch the grid and text color depending on background */ + int tcolor = GetRValue(ColorTable[0]) + + (int)(1.5 * GetGValue(ColorTable[0])) + GetBValue(ColorTable[0]); + if (tcolor > 360) { + ColorTable[1] = RGB(0, 0, 0); + i++; + bgisblack = FALSE; + continue; + } + else { + ColorTable[1] = RGB(255, 255, 255); + i++; + bgisblack = TRUE; + continue; + } + } + /* old code: beginning with 12 the colors are repeated */ + else if (!bgisblack && (i == 12)) + (void)strcpy(colorstring, "black"); + else + (void)strcpy(colorstring, stdcolornames[i]); + } + else if (ciprefix("rgb", colorstring)) { + ColorTable[i] = get_wincolor_rgb(colorstring); + i++; + continue; + } + ColorTable[i] = get_wincolor(colorstring, nocolor); + i++; + } +} + +COLORREF *get_wincolor_hash(char *name) +{ + return nghash_find(color_p, name); +} + +static COLORREF get_wincolor(char *name, int nocolor) +{ + + int i; + for (i = 0; i < nocolor; i++) { + if (ciprefix(name, ctable[i].name)) { + return ctable[i].rgbc; + } + } + fprintf(stderr, "Warning: Color %s is not available\n", name); + fprintf(stderr, " Color 'green' is returned instead!\n"); + return RGB(0, 255, 0); +} + +#endif diff --git a/src/frontend/wdisp/wincolor.h b/src/frontend/wdisp/wincolor.h new file mode 100644 index 000000000..e69de29bb diff --git a/src/frontend/wdisp/windisp.c b/src/frontend/wdisp/windisp.c index 598f613e0..9ed9df0df 100644 --- a/src/frontend/wdisp/windisp.c +++ b/src/frontend/wdisp/windisp.c @@ -4,6 +4,7 @@ * Holger Vogt 07.12.01 * Holger Vogt 05.12.07 * Holger Vogt 01.11.18 + * Holger Vogt 09.02.20 */ #include "ngspice/ngspice.h" @@ -64,6 +65,7 @@ extern HWND swString; /* string input window of main window */ extern int DevSwitch(char *devname); extern int NewViewport(GRAPH *pgraph); extern void com_hardcopy(wordlist *wl); +extern void wincolor_graph(COLORREF* ColorTable, int noc, GRAPH* graph); /* defines */ #define RAD_TO_DEG (180.0 / M_PI) @@ -73,6 +75,7 @@ extern void com_hardcopy(wordlist *wl); #endif #define DEF_FONTW "Arial" +#define DEFW_FONTW L"Arial" /* local variables */ static int IsRegistered = 0; /* 1 if window class is registered */ @@ -80,6 +83,8 @@ static int IsRegistered = 0; /* 1 if window class is regis static COLORREF ColorTable[NumWinColors]; /* color memory */ static char *WindowName = "Spice Plot"; /* window name */ static WNDCLASS TheWndClass; /* Plot-window class */ +static wchar_t * WindowNameW = L"Spice Plot"; /* window name */ +static WNDCLASSW TheWndClassW; /* Plot-window class */ static HFONT PlotFont; /* which font */ #define ID_DRUCKEN 0xEFF0 /* System Menue: print */ #define ID_DRUCKEINR 0xEFE0 /* System Menue: printer setup */ @@ -91,9 +96,17 @@ static char *STR_DRUCKEN = "Printer..."; /* System menue strings */ static char *STR_DRUCKEINR = "Printer setup..."; static char *STR_HARDCOPY = "Postscript file, color"; static char *STR_HARDCOPY_BW = "Postscript file, b&w"; +static wchar_t * STRW_DRUCKEN = L"Printer..."; /* System menue strings */ +static wchar_t * STRW_DRUCKEINR = L"Printer setup..."; +static wchar_t * STRW_HARDCOPY = L"Postscript file, color"; +static wchar_t * STRW_HARDCOPY_BW = L"Postscript file, b&w"; static bool isblack = TRUE; /* background color of plot is black */ static bool isblackold = TRUE; static int linewidth = 0; /* linewidth of grid and plot */ +static int gridlinewidth = 0; /* linewidth of grid */ + +extern void wincolor_init(COLORREF *ColorTable, int noc); +extern void wincolor_redo(COLORREF *ColorTable, int noc); /****************************************************************************** WIN_Init() makes connection to graphics. We have to determine @@ -109,7 +122,13 @@ WIN_Init() does not yet open a window, this happens only in WIN_NewViewport() ******************************************************************************/ int WIN_Init(void) { - char colorstring[BSIZE_SP]; + char facename[32]; + +#ifdef EXT_ASC + LOGFONT lf; +#else + LOGFONTW lfw; +#endif /* Initialization of display descriptor */ dispdev->width = GetSystemMetrics(SM_CXSCREEN); @@ -117,75 +136,12 @@ int WIN_Init(void) dispdev->numlinestyles = 5; /* see implications in WinPrint! */ dispdev->numcolors = NumWinColors; - /* always, user may have set color0 to white */ - /* get background color information from spinit, only "white" - is recognized as a suitable option! */ - if (cp_getvar("color0", CP_STRING, colorstring, sizeof(colorstring))) - isblack = !cieq(colorstring, "white"); - - /* get linewidth information from spinit */ - if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) { - linewidth = 0; - } - if (linewidth < 0) { - linewidth = 0; - } - /* only for the first time: */ if (!IsRegistered) { - isblackold = isblack; - - /* get linewidth information from spinit - * if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) - * linewidth = 0; - * if (linewidth < 0) - * linewidth = 0; - */ - - /* Initialize colors */ - if (isblack) { - ColorTable[0] = RGB( 0, 0, 0); /* black = background */ - ColorTable[1] = RGB(255, 255, 255); /* white = text and grid */ - } - else { - ColorTable[0] = RGB(255, 255, 255); /* white = background */ - ColorTable[1] = RGB( 0, 0, 0); /* black = text and grid */ - } - - ColorTable[2] = RGB( 0, 255, 0); /* green = first line */ - ColorTable[3] = RGB(255, 0, 0); /* red */ - ColorTable[4] = RGB( 0, 0, 255); /* blue */ - ColorTable[5] = RGB(255, 255, 0); /* yellow */ - ColorTable[6] = RGB(255, 0, 255); /* violett */ - ColorTable[7] = RGB( 0, 255, 255); /* azur */ - ColorTable[8] = RGB(255, 128, 0); /* orange */ - ColorTable[9] = RGB(128, 64, 0); /* brown */ - ColorTable[10] = RGB(128, 0, 255); /* light violett */ - ColorTable[11] = RGB(255, 128, 128); /* pink */ - - /* 2. color bank (with different line style */ - if (isblack) { - ColorTable[12] = RGB(255, 255, 255); /* white */ - } - else { - ColorTable[12] = RGB( 0, 0, 0); /* black */ - } - - ColorTable[13] = RGB( 0, 255, 0); /* green */ - ColorTable[14] = RGB(255, 0, 0); /* red */ - ColorTable[15] = RGB( 0, 0, 255); /* blue */ - ColorTable[16] = RGB(255, 255, 0); /* yellow */ - ColorTable[17] = RGB(255, 0, 255); /* violett */ - ColorTable[18] = RGB( 0, 255, 255); /* azur */ - ColorTable[19] = RGB(255, 128, 0); /* orange */ - ColorTable[20] = RGB(128, 64, 0); /* brown */ - ColorTable[21] = RGB(128, 0, 255); /* light violett */ - ColorTable[22] = RGB(255, 128, 128); /* pink */ - - /* Ansii fixed font */ - PlotFont = GetStockFont(ANSI_FIXED_FONT); + wincolor_init(ColorTable, NumWinColors); +#ifdef EXT_ASC /* register window class */ TheWndClass.lpszClassName = WindowName; TheWndClass.hInstance = hInst; @@ -207,28 +163,78 @@ int WIN_Init(void) if (!RegisterClass(&TheWndClass)) { return 1; - } - } - /* not first time */ - else if (isblackold != isblack) { - if (isblack) { - ColorTable[0] = RGB( 0, 0, 0); /* black = background */ - ColorTable[1] = RGB(255, 255, 255); /* white = text and grid */ - } - else { - ColorTable[0] = RGB(255, 255, 255); /* white = background */ - ColorTable[1] = RGB( 0, 0, 0); /* black = text and grid */ - } - if (isblack) { - ColorTable[12] = RGB(255, 255, 255); /* white */ - } - else { - ColorTable[12] = RGB( 0, 0, 0); /* black */ - } - isblackold = isblack; +#else + /* register window class */ + TheWndClassW.lpszClassName = WindowNameW; + TheWndClassW.hInstance = hInst; + TheWndClassW.lpfnWndProc = PlotWindowProc; + TheWndClassW.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; + TheWndClassW.lpszMenuName = NULL; + TheWndClassW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512) /*IDC_ARROW*/); + if (isblack) + TheWndClassW.hbrBackground = GetStockObject(BLACK_BRUSH); + else + TheWndClassW.hbrBackground = GetStockObject(WHITE_BRUSH); + TheWndClassW.hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(2)); + TheWndClassW.cbClsExtra = 0; + TheWndClassW.cbWndExtra = sizeof(GRAPH *); + if (!RegisterClassW(&TheWndClassW)) return 1; +#endif + IsRegistered = 1; } - IsRegistered = 1; + else + wincolor_redo(ColorTable, NumWinColors); + +#ifdef EXT_ASC + // lf.lfHeight = 18; + lf.lfWidth = 0; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfWeight = 500; + lf.lfItalic = 0; + lf.lfUnderline = 0; + lf.lfStrikeOut = 0; + lf.lfCharSet = 0; + lf.lfOutPrecision = 0; + lf.lfClipPrecision = 0; + lf.lfQuality = 0; + lf.lfPitchAndFamily = 0; + /* set up fonts */ + if (!cp_getvar("wfont", CP_STRING, lf.lfFaceName, strlen(lf.lfFaceName))) { + (void)lstrcpy(lf.lfFaceName, DEF_FONTW); + } + if (!cp_getvar("wfont_size", CP_NUM, &(lf.lfHeight), 0)) { + lf.lfHeight = 18; + } + PlotFont = CreateFontIndirect(&lf); +#else + // lfw.lfHeight = 18; + lfw.lfWidth = 0; + lfw.lfEscapement = 0; + lfw.lfOrientation = 0; + lfw.lfWeight = 500; + lfw.lfItalic = 0; + lfw.lfUnderline = 0; + lfw.lfStrikeOut = 0; + lfw.lfCharSet = 0; + lfw.lfOutPrecision = 0; + lfw.lfClipPrecision = 0; + lfw.lfQuality = 0; + lfw.lfPitchAndFamily = 0; + if (!cp_getvar("wfont", CP_STRING, facename, sizeof(facename))) { + (void)lstrcpyW(lfw.lfFaceName, DEFW_FONTW); + } + else { + wchar_t wface[32]; + swprintf(wface, 32, L"%S", facename); + (void)lstrcpyW(lfw.lfFaceName, wface); + } + if (!cp_getvar("wfont_size", CP_NUM, &(lfw.lfHeight), 0)) { + lfw.lfHeight = 18; + } + PlotFont = CreateFontIndirectW(&lfw); +#endif /* ready */ return 0; @@ -239,7 +245,11 @@ int WIN_Init(void) /* (attach to window) */ static GRAPH *pGraph(HWND hwnd) { +#ifdef EXT_ASC return (GRAPH *) GetWindowLongPtr(hwnd, 0); +#else + return (GRAPH *) GetWindowLongPtrW( hwnd, 0); +#endif } @@ -341,6 +351,19 @@ static LRESULT PrintInit(HWND hwnd) return 0; } +/* check if background color is dark enough. + Threshold is empirical by looking at color tables */ +static bool get_black(GRAPH* graph) +{ + int tcolor = GetRValue(graph->colorarray[0]) + + (int)(1.5 * GetGValue(graph->colorarray[0])) + + GetBValue(graph->colorarray[0]); + if (tcolor > 360) { + return FALSE; + } + else + return TRUE; +} /* window procedure */ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, @@ -387,6 +410,8 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, /* left mouse button: connect coordinate pair by dashed pair of x, y lines */ if (wParam & MK_LBUTTON) { hdc = GetDC(hwnd); + GRAPH* gr = pGraph(hwnd); + isblack = get_black(gr); if (isblack) { prevmix = SetROP2(hdc, R2_XORPEN); } @@ -394,7 +419,7 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, prevmix = SetROP2(hdc, R2_NOTXORPEN); } /* Create white dashed pen */ - NewPen = CreatePen(LType(12), 0, ColorTable[1]); + NewPen = CreatePen(LType(12), 0, gr->colorarray[1]); OldPen = SelectObject(hdc, NewPen); /* draw lines with previous coodinates -> delete old line because of XOR */ MoveToEx (hdc, x0, y0, NULL); @@ -419,12 +444,14 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, /* right mouse button: create white (black) dashed box */ else if (wParam & MK_RBUTTON) { hdc = GetDC (hwnd); + GRAPH* gr = pGraph(hwnd); + isblack = get_black(gr); if (isblack) prevmix = SetROP2(hdc, R2_XORPEN); else prevmix = SetROP2(hdc, R2_NOTXORPEN); /* Create white (black) dashed pen */ - NewPen = CreatePen(LType(12), 0, ColorTable[1]); + NewPen = CreatePen(LType(12), 0, gr->colorarray[1]); OldPen = SelectObject(hdc, NewPen); /* draw box with previous coodinates -> delete old lines because of XOR */ MoveToEx (hdc, x0, y0, NULL); @@ -527,11 +554,11 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, if (!eq(plot_cur->pl_typename, buf2)) { (void) sprintf(buf, // "setplot %s; %s xlimit %e %e ylimit %e %e; setplot $curplot\n", - "setplot %s; %s xlimit %e %e ylimit %e %e\n", - buf2, gr->commandline, fx0, fxe, fy0, fye); + "setplot %s; %s xlimit %e %e ylimit %e %e sgraphid %d\n", + buf2, gr->commandline, fx0, fxe, fy0, fye, gr->graphid); } else { - (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e\n", - gr->commandline, fx0, fxe, fy0, fye); + (void) sprintf(buf, "%s xlimit %e %e ylimit %e %e sgraphid %d\n", + gr->commandline, fx0, fxe, fy0, fye, gr->graphid); } (void) cp_evloop(buf); @@ -599,7 +626,11 @@ LRESULT CALLBACK PlotWindowProc(HWND hwnd, UINT uMsg, default: WIN_DEFAULT: +#ifdef EXT_ASC return DefWindowProc(hwnd, uMsg, wParam, lParam); +#else + return DefWindowProcW( hwnd, uMsg, wParam, lParam); +#endif } } @@ -616,9 +647,14 @@ int WIN_NewViewport(GRAPH *graph) int i; HWND window; HDC dc; +#ifdef EXT_ASC TEXTMETRIC tm; +#else + TEXTMETRICW tmw; +#endif tpWindowData wd; HMENU sysmenu; + GRAPH* pgraph = NULL; /* test the parameters */ if (!graph) { @@ -631,6 +667,16 @@ int WIN_NewViewport(GRAPH *graph) return 1; } + /* get the colors into graph struct */ + wincolor_graph(ColorTable, NumWinColors, graph); + /* If we had a previous graph, e.g. after zooming, we + have to set the background color already here, because + background is set below */ + if (graph->mgraphid > 0) { + pgraph = FindGraph(graph->mgraphid); + graph->colorarray[0] = pgraph->colorarray[0]; + } + /* allocate device dependency info */ wd = calloc(1, sizeof(tWindowData)); if (!wd) { @@ -642,22 +688,34 @@ int WIN_NewViewport(GRAPH *graph) /* Create the window */ i = GetSystemMetrics(SM_CYSCREEN) / 3; +#ifdef EXT_ASC window = CreateWindow(WindowName, graph->plotname, WS_OVERLAPPEDWINDOW, 0, 0, WinLineWidth, i * 2 - 22, NULL, NULL, hInst, NULL); - if (!window) { +#else + /* UTF-8 support */ + wchar_t *wtext, *wtext2; + wtext = TMALLOC(wchar_t, 2 * strlen(graph->plotname) + 1); + wtext2 = TMALLOC(wchar_t, 2 * strlen(WindowName) + 1); + /* translate UTF-8 to UTF-16 */ + MultiByteToWideChar(CP_UTF8, 0, graph->plotname, -1, wtext, 2 * strlen(graph->plotname) + 1); + MultiByteToWideChar(CP_UTF8, 0, WindowName, -1, wtext2, 2 * strlen(WindowName) + 1); + window = CreateWindowW(wtext2, wtext, WS_OVERLAPPEDWINDOW, + 0, 0, WinLineWidth, i * 2 - 22, NULL, NULL, hInst, NULL); + tfree(wtext); + tfree(wtext2); +#endif + if (!window) return 1; - } + SetClassLongPtr(window, GCLP_HBRBACKGROUND, (LONG_PTR)GetStockObject(DC_BRUSH)); + + /* get the DC */ + dc = GetDC(window); + wd->hDC = dc; - /* change the background color of all windows (both new and already plotted) - by assessing the registered window class */ - if (isblack) { - SetClassLongPtr(window, GCLP_HBRBACKGROUND, (LONG_PTR)GetStockObject(BLACK_BRUSH)); - } - else { - SetClassLongPtr(window, GCLP_HBRBACKGROUND, (LONG_PTR)GetStockObject(WHITE_BRUSH)); - } - + /* set the background color */ + SelectObject(dc, GetStockObject(DC_BRUSH)); + SetDCBrushColor(dc, graph->colorarray[0]); wd->wnd = window; SetWindowLongPtr(window, 0, (LONG_PTR)graph); @@ -668,10 +726,6 @@ int WIN_NewViewport(GRAPH *graph) /* get the mask */ GetClientRect(window, &(wd->Area)); - /* get the DC */ - dc = GetDC(window); - wd->hDC = dc; - /* set the Color Index */ wd->ColorIndex = 0; @@ -688,18 +742,24 @@ int WIN_NewViewport(GRAPH *graph) AppendMenu(sysmenu, MF_STRING, ID_HARDCOPY_BW, STR_HARDCOPY_BW); /* set default parameters of DC */ - SetBkColor(dc, ColorTable[0]); + SetBkColor(dc, graph->colorarray[0]); SetBkMode(dc, TRANSPARENT ); /* set font */ SelectObject(dc, PlotFont); /* query the font parameters */ +#ifdef EXT_ASC if (GetTextMetrics(dc, &tm)) { graph->fontheight = tm.tmHeight; graph->fontwidth = tm.tmAveCharWidth; } - +#else + if (GetTextMetricsW(dc, &tmw)) { + graph->fontheight = tmw.tmHeight; + graph->fontwidth = tmw.tmAveCharWidth + 1; /*FIXME relationship between height and width for various fonts*/ + } +#endif /* set viewport parameters */ graph->viewport.height = wd->Area.bottom; graph->viewport.width = wd->Area.right; @@ -710,6 +770,27 @@ int WIN_NewViewport(GRAPH *graph) graph->absolute.width = wd->Area.right; graph->absolute.height = wd->Area.bottom; + /* get linewidth information from .spiceinit or .control section */ + if (!cp_getvar("xbrushwidth", CP_NUM, &linewidth, 0)) + linewidth = 0; + if (linewidth < 0) + linewidth = 0; + if (pgraph) + graph->graphwidth = pgraph->graphwidth; + else + graph->graphwidth = linewidth; + + /* get linewidth information from .spiceinit or .control section */ + if (!cp_getvar("xgridwidth", CP_NUM, &gridlinewidth, 0)) + gridlinewidth = 0; + if (gridlinewidth < 0) + gridlinewidth = 0; + + if (pgraph) + graph->gridwidth = pgraph->gridwidth; + else + graph->gridwidth = gridlinewidth; + /* wait until the window is really there */ WaitForIdle(); @@ -767,7 +848,8 @@ int WIN_Clear(void) } -int WIN_DrawLine(int x1, int y1, int x2, int y2) +int +WIN_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { tpWindowData wd; HPEN OldPen; @@ -781,7 +863,10 @@ int WIN_DrawLine(int x1, int y1, int x2, int y2) return 0; MoveToEx(wd->hDC, x1, wd->Area.bottom - y1, NULL); - NewPen = CreatePen(LType(wd->ColorIndex), linewidth, ColorTable[wd->ColorIndex]); + if (isgrid) + NewPen = CreatePen(LType(wd->ColorIndex), currentgraph->gridwidth, currentgraph->colorarray[wd->ColorIndex]); + else + NewPen = CreatePen(LType(wd->ColorIndex), currentgraph->graphwidth, currentgraph->colorarray[wd->ColorIndex]); OldPen = SelectObject(wd->hDC, NewPen); LineTo(wd->hDC, x2, wd->Area.bottom - y2); OldPen = SelectObject(wd->hDC, OldPen); @@ -840,7 +925,7 @@ int WIN_Arc(int x0, int y0, int radius, double theta, double delta_theta) ye = (int)(dy0 + (r * sin(theta + delta_theta))); /* plot */ - NewPen = CreatePen(LType(wd->ColorIndex), linewidth, ColorTable[wd->ColorIndex]); + NewPen = CreatePen(LType(wd->ColorIndex), linewidth, currentgraph->colorarray[wd->ColorIndex]); OldPen = SelectObject(wd->hDC, NewPen); Arc(wd->hDC, left, yb-top, right, yb-bottom, xs, yb-ys, xe, yb-ye); OldPen = SelectObject(wd->hDC, OldPen); @@ -875,7 +960,13 @@ int WIN_Text(char *text, int x, int y, int angle) { tpWindowData wd; HFONT hfont; +#ifdef EXT_ASC LOGFONT lf; +#else + LOGFONTW lfw; +#endif + + if (!currentgraph) return 0; @@ -884,6 +975,7 @@ int WIN_Text(char *text, int x, int y, int angle) if (!wd) return 0; +#ifdef EXT_ASC lf.lfHeight = (int) (1.1 * currentgraph->fontheight); lf.lfWidth = 0; lf.lfEscapement = angle * 10; @@ -903,15 +995,60 @@ int WIN_Text(char *text, int x, int y, int angle) (void) lstrcpy(lf.lfFaceName, DEF_FONTW); if (!cp_getvar("wfont_size", CP_NUM, &(lf.lfHeight), 0)) - lf.lfHeight = (int) (1.3 * currentgraph->fontheight); + lf.lfHeight = 18; + //lf.lfHeight = (int) (1.3 * currentgraph->fontheight); + + hfont = CreateFontIndirect (&lf); +#else + char facename[32]; + lfw.lfHeight = (int)(1.1 * currentgraph->fontheight); + lfw.lfWidth = 0; + lfw.lfEscapement = angle * 10; + lfw.lfOrientation = angle * 10; + lfw.lfWeight = 500; + lfw.lfItalic = 0; + lfw.lfUnderline = 0; + lfw.lfStrikeOut = 0; + lfw.lfCharSet = 0; + lfw.lfOutPrecision = 0; + lfw.lfClipPrecision = 0; + lfw.lfQuality = 0; + lfw.lfPitchAndFamily = 0; + + /* set up fonts */ + if (!cp_getvar("wfont", CP_STRING, facename, sizeof(facename))) { + (void)lstrcpyW(lfw.lfFaceName, DEFW_FONTW); + } + else { + wchar_t wface[32]; + swprintf(wface, 32, L"%S", facename); + (void)lstrcpyW(lfw.lfFaceName, wface); + } + if (!cp_getvar("wfont_size", CP_NUM, &(lfw.lfHeight), 0)) { + lfw.lfHeight = 18; + } + else { + currentgraph->fontheight = lfw.lfHeight; + currentgraph->fontwidth = (int)(lfw.lfHeight*0.52); + } + + hfont = CreateFontIndirectW(&lfw); +#endif SelectObject(wd->hDC, hfont); - SetTextColor(wd->hDC, ColorTable[wd->ColorIndex]); + SetTextColor(wd->hDC, currentgraph->colorarray[wd->ColorIndex]); +#ifdef EXT_ASC TextOut(wd->hDC, x, wd->Area.bottom - y - currentgraph->fontheight, text, (int)strlen(text)); - - DeleteObject(SelectObject(wd->hDC, GetStockObject(SYSTEM_FONT))); +#else + wchar_t *wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(text) + 1); + MultiByteToWideChar(CP_UTF8, 0, text, -1, wtext, 2 * strlen(text) + 1); + TextOutW(wd->hDC, x, wd->Area.bottom - y - currentgraph->fontheight, wtext, 2 * (int)strlen(text) + 1); + tfree(wtext); +#endif + DeleteObject(SelectObject(wd->hDC, hfont)); return 0; } @@ -942,8 +1079,9 @@ int WIN_SetLinestyle(int style) } -int WIN_SetColor(int color) +int WIN_SetColor(int color, GRAPH *graph) { + NG_IGNORE(graph); tpWindowData wd; if (!currentgraph) @@ -1018,8 +1156,8 @@ static void WIN_ScreentoData(GRAPH *graph, int x, int y, double *fx, double *fy) { lmin = log10(graph->datawindow.ymin); lmax = log10(graph->datawindow.ymax); - *fy = exp(((graph->absolute.height - y - graph->viewportyoff) * - (lmax - lmin) / graph->viewport.height + lmin) * M_LN10); + *fy = exp(((graph->absolute.height - y - graph->viewportxoff) * + (lmax - lmin) / graph->viewport.height + lmin) * M_LN10); } else { *fy = ((graph->absolute.height - y) - graph->viewportyoff) * graph->aspectratioy + graph->datawindow.ymin; diff --git a/src/frontend/wdisp/winprint.c b/src/frontend/wdisp/winprint.c index e81fff873..de07b1f3a 100644 --- a/src/frontend/wdisp/winprint.c +++ b/src/frontend/wdisp/winprint.c @@ -31,7 +31,7 @@ #pragma hdrstop #endif /* _MSC_VER */ -#include "winprint.h" /* function prototypes */ +#include "winprint.h" /* function prototypes */ /* Typen */ typedef struct { /* Extra Printdaten */ @@ -42,21 +42,23 @@ typedef tPrintData *tpPrintData; /* Zeiger darauf */ #define pPrintData(g) ((tpPrintData)(g->devdep)) /* externals */ -void WaitForIdle(void); /* Warte, bis keine Events da */ + +void WaitForIdle(void); /* wait until no events */ +extern void wincolor_init(COLORREF* ColorTable, int noc); /* lokale Variablen */ -static HFONT PlotFont = NULL; /* Font-Merker */ -static HFONT OldFont = NULL; -#define NumLines 7 /* Anzahl der LineStyles */ -static int LineTable[NumLines]; /* Speicher fuer die LineStyles */ -static HDC PrinterDC = NULL; /* Device Context */ -#define NumPrintColors 2 /* vordef. Farben */ -static COLORREF ColorTable[NumPrintColors];/* Speicher fuer die Farben */ -static int PrinterWidth = 1000; /* Breite des Papiers */ -static int PrinterHeight = 1000; /* Hoehe des Papiers */ +static HFONT PlotFont = NULL; +static HFONT OldFont = NULL; +#define NumLines 7 /* number of LineStyles */ +static int LineTable[NumLines]; /* LineStyle memory */ +static HDC PrinterDC = NULL; /* Device Context */ +#define NumPrintColors 23 /* number of pre-defined colors */ +static COLORREF ColorTable[NumPrintColors]; /* color memory */ +static int PrinterWidth = 1000; /* paper width */ +static int PrinterHeight = 1000; /* paper height */ /****************************************************************************** - Drucker-Initialisierung + printer initialization ******************************************************************************/ void WPRINT_PrintInit(HWND hwnd) @@ -126,7 +128,7 @@ WPRINT_Init() gibt 0 zurueck, falls kein Fehler auftrat. int WPRINT_Init(void) { int pWidth; - int pHeight; + int pHeight; /* Printer-DC holen */ if (!PrinterDC) { @@ -156,39 +158,33 @@ int WPRINT_Init(void) pd.hSetupTemplate = NULL; /* Default-Drucker initialisieren */ - (void) PrintDlg(&pd); + (void) PrintDlg( &pd); /* Speicher freigeben */ - if (pd.hDevMode) { - GlobalFree(pd.hDevMode); - } - if (pd.hDevNames) { - GlobalFree(pd.hDevNames); - } + if( pd.hDevMode) GlobalFree( pd.hDevMode); + if( pd.hDevNames) GlobalFree( pd.hDevNames); /* DC holen */ PrinterDC = pd.hDC; if (!PrinterDC) return 1; /* Abmasze bestimmen */ - PrinterWidth = GetDeviceCaps(PrinterDC, HORZRES); - PrinterHeight = GetDeviceCaps(PrinterDC, VERTRES); - pWidth = GetDeviceCaps(PrinterDC, HORZSIZE); - pHeight = GetDeviceCaps(PrinterDC, VERTSIZE); + PrinterWidth = GetDeviceCaps( PrinterDC, HORZRES); + PrinterHeight = GetDeviceCaps( PrinterDC, VERTRES); + pWidth = GetDeviceCaps( PrinterDC, HORZSIZE); + pHeight = GetDeviceCaps( PrinterDC, VERTSIZE); /* Mapping Mode setzen (fuer Kreise) */ - if (pWidth > pHeight) { + if ( pWidth > pHeight) /* Querformat */ PrinterWidth = (PrinterHeight * pWidth) / pHeight; - } - else { + else /* Hochformat */ PrinterHeight = (PrinterWidth * pHeight) / pWidth; - } - SetMapMode(PrinterDC, MM_ISOTROPIC); - SetWindowExtEx(PrinterDC, PrinterWidth, PrinterHeight, NULL); - SetViewportExtEx(PrinterDC, PrinterWidth, PrinterHeight, NULL); + SetMapMode( PrinterDC, MM_ISOTROPIC); + SetWindowExtEx( PrinterDC, PrinterWidth, PrinterHeight, NULL); + SetViewportExtEx( PrinterDC, PrinterWidth, PrinterHeight, NULL); /* nicht hoeher als breit zeichnen */ if (pWidth < pHeight) { @@ -198,35 +194,34 @@ int WPRINT_Init(void) /* Initialisierungen des Display-Descriptors */ dispdev->width = PrinterWidth; - dispdev->height = PrinterHeight; + dispdev->height = PrinterHeight; dispdev->numlinestyles = NumLines; dispdev->numcolors = NumPrintColors; /* Farben initialisieren */ - ColorTable[0] = RGB(255,255,255); /* Weisz */ - ColorTable[1] = RGB(0, 0, 0); /* Schwarz */ + wincolor_init(ColorTable, NumPrintColors); /* LineStyles initialisieren */ LineTable[0] = PS_SOLID; - LineTable[1] = PS_DOT; /* Gitter */ + LineTable[1] = PS_DOT; /* Gitter */ LineTable[2] = PS_SOLID; /* Erste Linie */ - LineTable[3] = PS_DOT; /* Zweite Linie */ + LineTable[3] = PS_DOT; /* Zweite Linie */ LineTable[4] = PS_DASH; /* usw */ LineTable[5] = PS_DASHDOT; LineTable[6] = PS_DASHDOTDOT; /* Font */ if (!PlotFont) { - PlotFont = CreateFont(0,0,0,0, FW_DONTCARE, FALSE, FALSE, FALSE, + PlotFont = CreateFont( 0,0,0,0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FIXED_PITCH, NULL); } /* Abort-Prozedur setzen */ - SetAbortProc(PrinterDC, WPRINT_Abort); + SetAbortProc( PrinterDC, WPRINT_Abort); } /* fertig */ - return 0; + return (0); } @@ -239,14 +234,13 @@ int WPRINT_Init(void) int WPRINT_NewViewport(GRAPH * graph) { - TEXTMETRIC tm; - tpPrintData pd; - DOCINFO di; + + TEXTMETRIC tm; + tpPrintData pd; + DOCINFO di; /* Parameter testen */ - if (!graph) { - return 1; - } + if (!graph) return 1; /* Initialisiere, falls noch nicht geschehen */ if (WPRINT_Init() != 0) { @@ -258,16 +252,15 @@ int WPRINT_NewViewport(GRAPH * graph) pd = calloc(1, sizeof(tPrintData)); if (!pd) return 1; graph->devdep = pd; - graph->n_byte_devdep = sizeof(tPrintData); /* Setze den Color-Index */ pd->ColorIndex = 0; /* Font setzen */ - OldFont = SelectObject(PrinterDC, PlotFont); + OldFont = SelectObject( PrinterDC, PlotFont); /* Font-Parameter abfragen */ - if (GetTextMetrics(PrinterDC, &tm)) { + if (GetTextMetrics( PrinterDC, &tm)) { graph->fontheight = tm.tmHeight; graph->fontwidth = tm.tmAveCharWidth; } @@ -276,8 +269,8 @@ int WPRINT_NewViewport(GRAPH * graph) pd->LineIndex = 0; /* Viewport-Parameter setzen */ - graph->viewport.height = PrinterHeight; - graph->viewport.width = PrinterWidth; + graph->viewport.height = PrinterHeight; + graph->viewport.width = PrinterWidth; /* Absolut-Parameter setzen */ graph->absolute.xpos = 0; @@ -286,28 +279,32 @@ int WPRINT_NewViewport(GRAPH * graph) graph->absolute.height = PrinterHeight; /* Druckauftrag anmelden */ - di.cbSize = sizeof(DOCINFO); - di.lpszDocName = graph->plotname; - di.lpszOutput = NULL; - if (StartDoc(PrinterDC, &di) <= 0) { - return 1; - } - if (StartPage(PrinterDC) <= 0) { - return 1; - } + di.cbSize = sizeof( DOCINFO); + di.lpszDocName = graph->plotname; + di.lpszOutput = NULL; + if (StartDoc( PrinterDC, &di) <= 0) return 1; + if (StartPage( PrinterDC) <= 0) return 1; /* titel drucken */ if (graph->plotname) { UINT align; - align = GetTextAlign(PrinterDC); - SetTextAlign(PrinterDC, TA_RIGHT | TA_TOP | TA_NOUPDATECP); - TextOut(PrinterDC, PrinterWidth-graph->fontwidth, 1, graph->plotname, - (int) strlen(graph->plotname)); - SetTextAlign(PrinterDC, align); + align = GetTextAlign( PrinterDC); + SetTextAlign( PrinterDC, TA_RIGHT | TA_TOP | TA_NOUPDATECP); +#ifdef EXT_ASC + TextOut(PrinterDC, PrinterWidth - graph->fontwidth, 1, graph->plotname, + (int)strlen(graph->plotname)); +#else + wchar_t* wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(graph->plotname) + 1); + MultiByteToWideChar(CP_UTF8, 0, graph->plotname, -1, wtext, 2 * strlen(graph->plotname) + 1); + TextOutW(PrinterDC, PrinterWidth - graph->fontwidth, 1, wtext, 2 * (int)strlen(graph->plotname) + 1); + tfree(wtext); +#endif + SetTextAlign( PrinterDC, align); } /* fertig */ - return 0; + return(0); } int WPRINT_Close(void) @@ -333,12 +330,14 @@ int WPRINT_Clear(void) } -int WPRINT_DrawLine(int x1, int y1, int x2, int y2) +int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid) { + NG_IGNORE(isgrid); + tpPrintData pd; - HPEN OldPen; - HPEN NewPen; - int ColIndex; + HPEN OldPen; + HPEN NewPen; + int ColIndex; if (!currentgraph) return 0; pd = pPrintData(currentgraph); @@ -346,16 +345,14 @@ int WPRINT_DrawLine(int x1, int y1, int x2, int y2) /* Farben/Dicke */ ColIndex = pd->ColorIndex; - if (ColIndex > 1) - ColIndex = 1; MoveToEx(PrinterDC, x1, PrinterHeight - y1, NULL); - NewPen = CreatePen(LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); + NewPen = CreatePen( LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); OldPen = SelectObject(PrinterDC, NewPen); LineTo(PrinterDC, x2, PrinterHeight - y2); OldPen = SelectObject(PrinterDC, OldPen); - DeleteObject(NewPen); - return 0; + DeleteObject( NewPen); + return (0); } @@ -378,18 +375,11 @@ int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta) double dx0; double dy0; - if (!currentgraph) { - return 0; - } + if (!currentgraph) return 0; pd = pPrintData(currentgraph); - if (!pd) { - return 0; - } + if (!pd) return 0; ColIndex = pd->ColorIndex; - if (ColIndex > 1) { - ColIndex = 1; - } direction = AD_COUNTERCLOCKWISE; if (delta_theta < 0) { @@ -397,7 +387,7 @@ int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta) delta_theta = - delta_theta; direction = AD_CLOCKWISE; } - SetArcDirection(PrinterDC, direction); + SetArcDirection( PrinterDC, direction); /* Geometrische Vorueberlegungen */ yb = PrinterHeight; @@ -409,17 +399,17 @@ int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta) r = radius; dx0 = x0; dy0 = y0; - xs = (int) (dx0 + (r * cos(theta))); - ys = (int) (dy0 + (r * sin(theta))); - xe = (int) (dx0 + (r * cos(theta + delta_theta))); - ye = (int) (dy0 + (r * sin(theta + delta_theta))); + xs = (int)(dx0 + (r * cos(theta))); + ys = (int)(dy0 + (r * sin(theta))); + xe = (int)(dx0 + (r * cos(theta + delta_theta))); + ye = (int)(dy0 + (r * sin(theta + delta_theta))); /* Zeichnen */ - NewPen = CreatePen(LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); + NewPen = CreatePen( LineTable[pd->LineIndex], 0, ColorTable[ColIndex] ); OldPen = SelectObject(PrinterDC, NewPen); - Arc(PrinterDC, left, yb-top, right, yb-bottom, xs, yb-ys, xe, yb-ye); + Arc( PrinterDC, left, yb-top, right, yb-bottom, xs, yb-ys, xe, yb-ye); OldPen = SelectObject(PrinterDC, OldPen); - DeleteObject(NewPen); + DeleteObject( NewPen); return 0; } @@ -430,23 +420,24 @@ int WPRINT_Text(char * text, int x, int y, int degrees) int ColIndex; NG_IGNORE(degrees); - if (!currentgraph) { - return 0; - } + if (!currentgraph) return 0; pd = pPrintData(currentgraph); - if (!pd) { - return 0; - } + if (!pd) return 0; ColIndex = pd->ColorIndex; - if (ColIndex > 1) { - ColIndex = 1; - } - SetTextColor(PrinterDC, ColorTable[ColIndex]); - TextOut(PrinterDC, x, PrinterHeight - y - currentgraph->fontheight, - text, (int) strlen(text)); - return 0; + SetTextColor( PrinterDC, ColorTable[ColIndex]); + +#ifdef EXT_ASC + TextOut(PrinterDC, x, PrinterHeight - y - currentgraph->fontheight, text, (int)strlen(text)); +#else + wchar_t* wtext; + wtext = TMALLOC(wchar_t, 2 * strlen(text) + 1); + MultiByteToWideChar(CP_UTF8, 0, text, -1, wtext, 2 * strlen(text) + 1); + TextOutW(PrinterDC, x, PrinterHeight - y - currentgraph->fontheight, wtext, 2 * (int)strlen(text) + 1); + tfree(wtext); +#endif + return (0); } diff --git a/src/frontend/wdisp/winprint.h b/src/frontend/wdisp/winprint.h index 8a92992b0..f6d591d02 100644 --- a/src/frontend/wdisp/winprint.h +++ b/src/frontend/wdisp/winprint.h @@ -11,7 +11,7 @@ int WPRINT_Init(void); int WPRINT_NewViewport( GRAPH * graph); int WPRINT_Close(void); int WPRINT_Clear(void); -int WPRINT_DrawLine(int x1, int y1, int x2, int y2); +int WPRINT_DrawLine(int x1, int y1, int x2, int y2, bool isgrid); int WPRINT_Arc(int x0, int y0, int radius, double theta, double delta_theta); int WPRINT_Text( char * text, int x, int y, int degrees); int WPRINT_DefineColor(int colorid, double red, double green, double blue); diff --git a/src/include/ngspice/cpextern.h b/src/include/ngspice/cpextern.h index 8d18caf34..539ea9c9f 100644 --- a/src/include/ngspice/cpextern.h +++ b/src/include/ngspice/cpextern.h @@ -134,11 +134,6 @@ extern void out_send(char *string); /* quote.c */ extern char *cp_unquote(const char *string); -extern void cp_quoteword(char *str); -extern void cp_striplist(wordlist *wlist); -extern void cp_wstrip(char *str); - - /* unixcom.c */ diff --git a/src/include/ngspice/dvec.h b/src/include/ngspice/dvec.h index 3833295b7..ea0a9b83c 100644 --- a/src/include/ngspice/dvec.h +++ b/src/include/ngspice/dvec.h @@ -22,7 +22,7 @@ enum dvec_flags { /* Plot types. */ typedef enum { - PLOT_LIN, PLOT_COMB, PLOT_POINT, PLOT_MONOLIN + PLOT_LIN, PLOT_COMB, PLOT_POINT, PLOT_RETLIN } PLOTTYPE; diff --git a/src/include/ngspice/ftedev.h b/src/include/ngspice/ftedev.h index b8f3cc12b..530f497ac 100644 --- a/src/include/ngspice/ftedev.h +++ b/src/include/ngspice/ftedev.h @@ -18,13 +18,13 @@ typedef int disp_fn_Init_t (void); typedef int disp_fn_NewViewport_t (struct graph *); typedef int disp_fn_Close_t (void); typedef int disp_fn_Clear_t (void); -typedef int disp_fn_DrawLine_t (int x1, int y1, int x2, int y2); +typedef int disp_fn_DrawLine_t (int x1, int y1, int x2, int y2, bool isgrid); typedef int disp_fn_Arc_t (int x0, int y0, int radius, double theta, double delta_theta); typedef int disp_fn_Text_t (char *text, int x, int y, int angle); typedef int disp_fn_DefineColor_t (int colorid, double red, double green, double blue); typedef int disp_fn_DefineLinestyle_t (int linestyleid, int mask); typedef int disp_fn_SetLinestyle_t (int linestyleid); -typedef int disp_fn_SetColor_t (int colorid); +typedef int disp_fn_SetColor_t (int colorid, GRAPH *graf); typedef int disp_fn_Update_t (void); typedef int disp_fn_Track_t (void); typedef int disp_fn_MakeMenu_t (void); diff --git a/src/include/ngspice/graph.h b/src/include/ngspice/graph.h index b682f377f..e7b64d615 100644 --- a/src/include/ngspice/graph.h +++ b/src/include/ngspice/graph.h @@ -61,6 +61,7 @@ struct graph { int ticmarks; /* mark every ticmark'th point */ double *ticdata; + char ticchar[2]; int fontwidth, fontheight; /* for use in grid */ PLOTTYPE plottype; /* defined in FTEconstant.h */ @@ -104,6 +105,16 @@ struct graph { /* for zoomin */ char *commandline; + /* colors used */ + unsigned long colorarray[25]; + + /* we have a mother graph */ + int mgraphid; + + /* linewidths */ + int graphwidth; + int gridwidth; + /* Space here is allocated by NewViewport and de-allocated by DestroyGraph. */ diff --git a/src/include/ngspice/ngspice.h b/src/include/ngspice/ngspice.h index 61fa2a743..cb94792a6 100644 --- a/src/include/ngspice/ngspice.h +++ b/src/include/ngspice/ngspice.h @@ -223,6 +223,13 @@ extern double x_atanh(double); #endif #endif +#ifndef EXT_ASC +#if defined(__MINGW__) || defined(_MSC_VER) +#define fopen newfopen +extern FILE *newfopen(const char *fn, const char* md); +#endif +#endif + #if defined(__GNUC__) #define ATTRIBUTE_NORETURN __attribute__ ((noreturn)) #elif defined(_MSC_VER) diff --git a/src/include/ngspice/wincolornames.h b/src/include/ngspice/wincolornames.h new file mode 100644 index 000000000..71fff4c9a --- /dev/null +++ b/src/include/ngspice/wincolornames.h @@ -0,0 +1,170 @@ +/* list of available colors + according to + https://www.codeproject.com/Articles/1276/Naming-Common-Colors +*/ + +#if !defined(__ID_COLOR_NAMES_H) +#define __ID_COLOR_NAMES_H + +struct colortable { + COLORREF rgbc; + char name[32]; + int R; + int G; + int B; +}; + +static struct colortable ctable[] = { + 0, "AliceBlue ",240,248,255, + 0, "AntiqueWhite ",250,235,215, + 0, "Aqua ", 0,255,255, + 0, "Aquamarine ",127,255,212, + 0, "Azure ",240,255,255, + 0, "Beige ",245,245,220, + 0, "Bisque ",255,228,196, + 0, "Black ", 0, 0, 0, + 0, "BlanchedAlmond ",255,255,205, + 0, "Blue ", 0, 0,255, + 0, "BlueViolet ",138, 43,226, + 0, "Brown ",165, 42, 42, + 0, "Burlywood ",222,184,135, + 0, "CadetBlue ", 95,158,160, + 0, "Chartreuse ",127,255, 0, + 0, "Chocolate ",210,105, 30, + 0, "Coral ",255,127, 80, + 0, "CornflowerBlue ",100,149,237, + 0, "Cornsilk ",255,248,220, + 0, "Crimson ",220, 20, 60, + 0, "Cyan ", 0,255,255, + 0, "DarkBlue ", 0, 0,139, + 0, "DarkCyan ", 0,139,139, + 0, "DarkGoldenRod ",184,134, 11, + 0, "DarkGray ",169,169,169, + 0, "DarkGreen ", 0,100, 0, + 0, "DarkKhaki ",189,183,107, + 0, "DarkMagenta ",139, 0,139, + 0, "DarkOliveGreen ", 85,107, 47, + 0, "DarkOrange ",255,140, 0, + 0, "DarkOrchid ",153, 50,204, + 0, "DarkRed ",139, 0, 0, + 0, "DarkSalmon ",233,150,122, + 0, "DarkSeaGreen ",143,188,143, + 0, "DarkSlateBlue ", 72, 61,139, + 0, "DarkSlateGray ", 47, 79, 79, + 0, "DarkTurquoise ", 0,206,209, + 0, "DarkViolet ",148, 0,211, + 0, "DeepPink ",255, 20,147, + 0, "DeepSkyBlue ", 0,191,255, + 0, "DimGray ",105,105,105, + 0, "DodgerBlue ", 30,144,255, + 0, "FireBrick ",178, 34, 34, + 0, "FloralWhite ",255,250,240, + 0, "ForestGreen ", 34,139, 34, + 0, "Fuchsia ",255, 0,255, + 0, "Gainsboro ",220,220,220, + 0, "GhostWhite ",248,248,255, + 0, "Gold ",255,215, 0, + 0, "GoldenRod ",218,165, 32, + 0, "Gray ",127,127,127, + 0, "Green ", 0,255, 0, + 0, "GreenYellow ",173,255, 47, + 0, "HoneyDew ",240,255,240, + 0, "HotPink ",255,105,180, + 0, "IndianRed ",205, 92, 92, + 0, "Indigo ", 75, 0,130, + 0, "Ivory ",255,255,240, + 0, "Khaki ",240,230,140, + 0, "Lavender ",230,230,250, + 0, "LavenderBlush ",255,240,245, + 0, "Lawngreen ",124,252, 0, + 0, "LemonChiffon ",255,250,205, + 0, "LightBlue ",173,216,230, + 0, "LightCoral ",240,128,128, + 0, "LightCyan ",224,255,255, + 0, "LightGoldenRodYellow ",250,250,210, + 0, "LightGreen ",144,238,144, + 0, "LightGrey ",211,211,211, + 0, "LightPink ",255,182,193, + 0, "LightSalmon ",255,160,122, + 0, "LightSeaGreen ", 32,178,170, + 0, "LightSkyBlue ",135,206,250, + 0, "LightSlateGray ",119,136,153, + 0, "LightSteelBlue ",176,196,222, + 0, "Light Violet ",128, 0,255, + 0, "LightYellow ",255,255,224, + 0, "Lime ", 0,255, 0, + 0, "LimeGreen ", 50,205, 50, + 0, "Linen ",250,240,230, + 0, "Magenta ",255, 0,255, + 0, "Maroon ",128, 0, 0, + 0, "MediumAquamarine ",102,205,170, + 0, "MediumBlue ", 0, 0,205, + 0, "MediumOrchid ",186, 85,211, + 0, "MediumPurple ",147,112,219, + 0, "MediumSeaGreen ", 60,179,113, + 0, "MediumSlateBlue ",123,104,238, + 0, "MediumSpringGreen ", 0,250,154, + 0, "MediumTurquoise ", 72,209,204, + 0, "MediumVioletRed ",199, 21,133, + 0, "MidnightBlue ", 25, 25,112, + 0, "MintCream ",245,255,250, + 0, "MistyRose ",255,228,225, + 0, "Moccasin ",255,228,181, + 0, "NavajoWhite ",255,222,173, + 0, "Navy ", 0, 0,128, + 0, "Navyblue ",159,175,223, + 0, "OldLace ",253,245,230, + 0, "Olive ",128,128, 0, + 0, "OliveDrab ",107,142, 35, + 0, "Orange ",255,165, 0, + 0, "OrangeRed ",255, 69, 0, + 0, "Orchid ",218,112,214, + 0, "PaleGoldenRod ",238,232,170, + 0, "PaleGreen ",152,251,152, + 0, "PaleTurquoise ",175,238,238, + 0, "PaleVioletRed ",219,112,147, + 0, "PapayaWhip ",255,239,213, + 0, "PeachPuff ",255,218,185, + 0, "Peru ",205,133, 63, + 0, "Pink ",255,192,203, + 0, "Plum ",221,160,221, + 0, "PowderBlue ",176,224,230, + 0, "Purple ",128, 0,128, + 0, "Red ",255, 0, 0, + 0, "RosyBrown ",188,143,143, + 0, "RoyalBlue ", 65,105,225, + 0, "SaddleBrown ",139, 69, 19, + 0, "Salmon ",250,128,114, + 0, "SandyBrown ",244,164, 96, + 0, "SeaGreen ", 46,139, 87, + 0, "SeaShell ",255,245,238, + 0, "Sienna ",160, 82, 45, + 0, "Silver ",192,192,192, + 0, "SkyBlue ",135,206,235, + 0, "SlateBlue ",106, 90,205, + 0, "SlateGray ",112,128,144, + 0, "Snow ",255,250,250, + 0, "SpringGreen ", 0,255,127, + 0, "SteelBlue ", 70,130,180, + 0, "Tan ",210,180,140, + 0, "Teal ", 0,128,128, + 0, "Thistle ",216,191,216, + 0, "Tomato ",255, 99, 71, + 0, "Turquoise ", 64,224,208, + 0, "Violet ",238,130,238, + 0, "WebGreen ", 0,128, 0, + 0, "Wheat ",245,222,179, + 0, "White ",255,255,255, + 0, "WhiteSmoke ",245,245,245, + 0, "Yellow ",255,255, 0, + 0, "YellowGreen ",139,205, 50 +}; + +char* stdcolornames[] = +{ + "black", "white", "green", "red", "blue", "yellow", "violet", + "azure", "orange", "brown", "light violet", "pink", + "white", "green", "red", "blue", "yellow", "violet", + "azure", "orange", "brown", "light violet", "pink" +}; +#endif // __ID_COLOR_NAMES diff --git a/src/include/ngspice/wordlist.h b/src/include/ngspice/wordlist.h index 713ef26a2..2978d0482 100644 --- a/src/include/ngspice/wordlist.h +++ b/src/include/ngspice/wordlist.h @@ -34,19 +34,4 @@ void wl_sort(wordlist *wl); wordlist * wl_splice(wordlist *elt, wordlist *list); - - - -#ifdef QUOTE_CHAR -/* For quoting individual characters. '' strings are all quoted, but - * `` and "" strings are maintained as single words with the quotes - * around them. Note that this won't work on non-ascii machines. */ -#define quote(c) ((c) | 0200) -#define strip(c) ((c) & 0177) -#else -#define quote(c) (c) -#define strip(c) (c) -#endif - - #endif diff --git a/src/main.c b/src/main.c index d552a122f..7126766ce 100644 --- a/src/main.c +++ b/src/main.c @@ -544,14 +544,14 @@ prompt(void) s = "->"; while (*s) { - char c = (char) strip(*s++); + char c = (char) (*s++); switch (c) { case '!': p += sprintf(p, "%d", where_history() + 1); break; case '\\': if (*s) - c = (char) strip(*s++); + c = (char) (*s++); default: *p++ = c; break; diff --git a/src/maths/sparse/spfactor.c b/src/maths/sparse/spfactor.c index dcfad94ac..337ad2ace 100644 --- a/src/maths/sparse/spfactor.c +++ b/src/maths/sparse/spfactor.c @@ -56,15 +56,24 @@ * Matrix type and macro definitions for the sparse matrix routines. */ #include - #define spINSIDE_SPARSE #include "spconfig.h" #include "ngspice/spmatrix.h" #include "spdefs.h" - - - +#ifdef HAS_WINGUI +extern void SetAnalyse(char *Analyse, int Percent); +/* to increase responsiveness of Windows GUI */ +#define INCRESP \ +do { \ + static int ii = 100; \ + ii--;\ + if (ii == 0) { \ + SetAnalyse("or", 0); \ + ii = 100; \ + } \ +} while(0) +#endif /* * Function declarations @@ -214,6 +223,10 @@ spOrderAndFactor(MatrixPtr Matrix, RealNumber RHS[], RealNumber RelThreshold, if (!Matrix->NeedsOrdering) { /* Matrix has been factored before and reordering is not required. */ for (Step = 1; Step <= Size; Step++) { +#ifdef HAS_WINGUI + /* macro to improve responsiveness of Windows GUI */ + INCRESP; +#endif pPivot = Matrix->Diag[Step]; LargestInCol = FindLargestInCol(pPivot->NextInCol); if ((LargestInCol * RelThreshold < ELEMENT_MAG(pPivot))) { @@ -258,6 +271,10 @@ spOrderAndFactor(MatrixPtr Matrix, RealNumber RHS[], RealNumber RelThreshold, /* Perform reordering and factorization. */ for (; Step <= Size; Step++) { +#ifdef HAS_WINGUI + /* macro to improve responsiveness of Windows GUI */ + INCRESP; +#endif pPivot = SearchForPivot( Matrix, Step, DiagPivoting ); if (pPivot == NULL) return MatrixIsSingular( Matrix, Step ); ExchangeRowsAndCols( Matrix, pPivot, Step ); diff --git a/src/misc/util.c b/src/misc/util.c index 6801eb860..132560903 100644 --- a/src/misc/util.c +++ b/src/misc/util.c @@ -257,3 +257,27 @@ ngdirname(const char *name) } #endif + +/* Replacement for fopen, when using wide chars (utf-16) */ +#ifndef EXT_ASC +#if defined(__MINGW__) || defined(_MSC_VER) +#undef BOOLEAN +#include +FILE * +newfopen(const char *fn, const char* md) +{ + if (fn == NULL) + return NULL; + wchar_t wfn[BSIZE_SP]; + wchar_t wmd[16]; + MultiByteToWideChar(CP_UTF8, 0, md, -1, wmd, 15); + if (MultiByteToWideChar(CP_UTF8, 0, fn, -1, wfn, BSIZE_SP - 1) == 0) { + fprintf(stderr, "UTF-8 to UTF-16 conversion failed with 0x%x\n", GetLastError()); + fprintf(stderr, "%s could not be converted\n", fn); + return NULL; + } + return _wfopen(wfn, wmd); +} +#endif +#endif + diff --git a/src/misc/wlist.c b/src/misc/wlist.c index e94fa93b3..f6d9e2592 100644 --- a/src/misc/wlist.c +++ b/src/misc/wlist.c @@ -82,7 +82,7 @@ printword(const char *string, FILE *fp) { if (string) { while (*string) { - putc(strip(*string++), fp); + putc((*string++), fp); } } } diff --git a/src/spicelib/devices/cktask.c b/src/spicelib/devices/cktask.c index 203ac836c..9c9f9a453 100644 --- a/src/spicelib/devices/cktask.c +++ b/src/spicelib/devices/cktask.c @@ -29,7 +29,13 @@ CKTask(CKTcircuit *ckt, GENinstance *instance, int which, IFvalue *value, IFvalu } if (error && ft_stricterror) { fprintf(stderr, "\nError: %s\n", errMsg); + FREE(errMsg); controlled_exit(EXIT_BAD); } + if (error && ft_ngdebug) { + printf("\nWarning: %s\n", errMsg); + } + if (errMsg) + FREE(errMsg); return(error); } diff --git a/src/tclspice.c b/src/tclspice.c index ff10db030..367eb334e 100644 --- a/src/tclspice.c +++ b/src/tclspice.c @@ -1633,6 +1633,8 @@ sp_Tk_Arc(int x0, int y0, int radius, double theta, double delta_theta) int sp_Tk_Text(char *text, int x, int y, int angle) { + NG_IGNORE(angle); + char buf[1024]; NG_IGNORE(angle); sprintf(buf, "spice_gr_Text \"%s\" %i %i", text, x, y); diff --git a/src/winmain.c b/src/winmain.c index c1498dee7..cbacdd7d4 100644 --- a/src/winmain.c +++ b/src/winmain.c @@ -2,7 +2,9 @@ Autor: Wolfgang Muees Stand: 28.10.97 Copyright: Holger Vogt + Stand: 09.01.2018 Stand: 20.07.2019 + Stand: 07.12.2019 Modified BSD license */ @@ -30,6 +32,7 @@ #include "hist_info.h" /* history management */ #include "ngspice/bool.h" /* bool defined as unsigned char */ #include "misc/misc_time.h" /* timediff */ +#include "ngspice/memory.h" /* TMALLOC */ #include "winmain.h" /* Constants */ @@ -39,7 +42,7 @@ #define LF 10 // Line Feed #define SE 0 // String termination #define BorderSize 8 // Umrandung des Stringfeldes -#define SBufSize 100 // Groesze des Stringbuffers +#define SBufSize 300 // Groesze des Stringbuffers #define IOBufSize 16348 // Groesze des printf-Buffers #define HIST_SIZE 20 /* Max # commands held in history */ #define N_BYTE_HIST_BUF 512 /* Initial size of history buffer in bytes */ @@ -75,29 +78,48 @@ HWND hwAnalyse; /* analysis window */ HWND hwQuitButton; /* Pause button */ static int nReturnCode = 0; /* WinMain return value */ static int nShowState; /* Display mode of main window */ +#ifdef EXT_ASC static WNDCLASS hwMainClass; /* Class definition for the main window */ static LPCTSTR hwClassName = "SPICE_TEXT_WND";/* Class name of the main window */ static LPCTSTR hwWindowName = PACKAGE_STRING; /* main window displayed name */ static WNDCLASS twTextClass; /* Class definition for the text box */ static LPCTSTR twClassName = "SPICE_TEXT_BOX"; /* Class name for the text box */ static LPCTSTR twWindowName = "TextOut"; /* text box name */ -static size_t TBufEnd = 0; /* Pointer to \0 */ -static char TBuffer[TBufSize + 1]; /* Text buffer */ -static SBufLine SBuffer; /* Input buffer */ static WNDCLASS swStringClass; /* Class definition of string window */ static LPCTSTR swClassName = "SPICE_STR_IN"; /* Class name of text input */ static LPCTSTR swWindowName = "StringIn"; /* Window name */ -static char CRLF[] = {CR, LF, SE}; /* CR/LF */ static WNDCLASS hwElementClass; /* Class definition of status displays */ static LPCTSTR hwElementClassName = "ElementClass"; static LPCTSTR hwSourceWindowName = "SourceDisplay"; static LPCTSTR hwAnalyseWindowName = "AnalyseDisplay"; +#else +static WNDCLASSW hwMainClassW; /* Class definition for the main window */ +static LPCWSTR hwClassNameW = L"SPICE_TEXT_WND";/* Class name of the main window */ +static LPCWSTR hwWindowNameW = L"ngspice 26"; /* main window displayed name */ +static WNDCLASSW twTextClassW; /* Class definition for the text box */ +static LPCWSTR twClassNameW = L"SPICE_TEXT_BOX"; /* Class name for the text box */ +static LPCWSTR twWindowNameW = L"TextOut"; /* text box name */ +static WNDCLASSW swStringClassW; /* Class definition of string window */ +static LPCWSTR swClassNameW = L"SPICE_STR_IN"; /* Class name of text input */ +static LPCWSTR swWindowNameW = L"StringIn"; /* Window name */ +static WNDCLASSW hwElementClassW; /* Class definition of status displays */ +static LPCWSTR hwElementClassNameW = L"ElementClass"; +static LPCWSTR hwSourceWindowNameW = L"SourceDisplay"; +static LPCWSTR hwAnalyseWindowNameW = L"AnalyseDisplay"; +#endif +static size_t TBufEnd = 0; /* Pointer to \0 */ +static char TBuffer[TBufSize + 1]; /* Text buffer */ +static SBufLine SBuffer; /* Input buffer */ +static char CRLF[] = {CR, LF, SE}; /* CR/LF */ static int RowHeight = 16; /* Height of line of text */ static int LineHeight = 25; /* Height of input line */ static int VisibleRows = 10; /* Number of visible lines in text window */ static BOOL DoUpdate = FALSE; /* Update text window */ static WNDPROC swProc = NULL; /* original string window procedure */ static WNDPROC twProc = NULL; /* original text window procedure */ +static HFONT efont; /* Font for element windows */ +static HFONT tfont; /* Font for text window */ +static HFONT sfont; /* Font for string window */ extern bool ft_ngdebug; /* some additional debug info printed */ extern bool ft_batchmode; @@ -105,12 +127,8 @@ extern FILE *flogp; /* definition see xmain.c, stdout redirected to file */ extern void cp_doquit(void); - - static struct History_info *init_history(void); - - // ---------------------------------------------------------- // Warte, bis keine Messages mehr zu bearbeiten sind @@ -160,9 +178,17 @@ void SetSource(char *Name) { if (hwSource) { +#ifdef EXT_ASC SetWindowText(hwSource, Name); +#else + wchar_t *NameW; + NameW = TMALLOC(wchar_t, 2 * strlen(Name) + 1); + MultiByteToWideChar(CP_UTF8, 0, Name, -1, NameW, 2 * (int)strlen(Name) + 1); + SetWindowTextW(hwSource, NameW); + tfree(NameW); +#endif InvalidateRgn(hwSource, NULL, TRUE); - } + } } @@ -186,7 +212,9 @@ SetAnalyse(char *Analyse, /* in: analysis type */ WaitForIdle(); - if ((DecaPercent == OldPercent) && !strcmp(OldAn, Analyse)) + OldAn[127] = '\0'; + + if (((DecaPercent == OldPercent) && !strcmp(OldAn, Analyse)) || !strcmp(Analyse, "or")) return; /* get actual time */ @@ -203,21 +231,21 @@ SetAnalyse(char *Analyse, /* in: analysis type */ OldPercent = DecaPercent; /* output only into hwAnalyse window and if time elapsed is larger than DELTATIME given value, or if analysis has changed, else return */ - if (((diffsec > 0) || (diffmillisec > DELTATIME) || strcmp(OldAn, Analyse))) { + if (hwAnalyse && ((diffsec > 0) || (diffmillisec > DELTATIME) || strcmp(OldAn, Analyse))) { if (DecaPercent < 0) { - sprintf(s, "--ready--"); + sprintf(s, " -- ready --"); sprintf(t, "%s", PACKAGE_STRING); } else if (DecaPercent == 0) { - sprintf(s, "%s", Analyse); + sprintf(s, " %s", Analyse); sprintf(t, "%s %s", PACKAGE_STRING, Analyse); } else if (!strcmp(Analyse, "shooting")) { - sprintf(s, "%s: %d", Analyse, DecaPercent); + sprintf(s, " %s: %d", Analyse, DecaPercent); sprintf(t, "%s %d", PACKAGE_STRING, DecaPercent); } else { - sprintf(s, "%s: %3.1f%%", Analyse, (double)DecaPercent/10.); + sprintf(s, " %s: %3.1f%%", Analyse, (double)DecaPercent/10.); sprintf(t, "%s %3.1f%%", PACKAGE_STRING, (double)DecaPercent/10.); } timebefore.dstflag = timenow.dstflag; @@ -231,13 +259,24 @@ SetAnalyse(char *Analyse, /* in: analysis type */ strncpy(OldAn, Analyse, 127); } +#ifdef EXT_ASC SetWindowText(hwAnalyse, s); SetWindowText(hwMain, t); +#else + wchar_t sw[256]; + wchar_t tw[256]; + swprintf(sw, 256, L"%S", s); + swprintf(tw, 256, L"%S", t); + /* Analysis window */ + SetWindowTextW(hwAnalyse, sw); + /* ngspice task bar */ + SetWindowTextW(hwMain, tw); +#endif InvalidateRgn(hwAnalyse, NULL, TRUE); + UpdateWindow(hwAnalyse); InvalidateRgn(hwMain, NULL, TRUE); + UpdateWindow(hwMain); } - UpdateWindow(hwAnalyse); - UpdateWindow(hwMain); } @@ -359,8 +398,17 @@ AppendString(const char *Line) static void DisplayText(void) { - // Darstellen + // Show text +#ifdef EXT_ASC Edit_SetText(twText, TBuffer); +#else + wchar_t *TWBuffer; + TWBuffer = TMALLOC(wchar_t, 2 * strlen(TBuffer) + 1); + if (MultiByteToWideChar(CP_UTF8, 0, TBuffer, -1, TWBuffer, 2 * (int)strlen(TBuffer) + 1) == 0) + swprintf(TWBuffer, 2 * strlen(TBuffer), L"UTF-8 to UTF-16 conversion failed with 0x%x\n%hs could not be converted\n", GetLastError(), TBuffer); + SetWindowTextW(twText, TWBuffer); + tfree(TWBuffer); +#endif // Scroller updaten, neuen Text darstellen AdjustScroller(); } @@ -454,14 +502,12 @@ Main_OnSize(HWND hwnd, UINT state, int cx, int cy) MoveWindow(swString, 0, h, cx, LineHeight, TRUE); /* Expand Status Elements */ - h = cy - LineHeight + StatusFrame - 1; - MoveWindow(hwSource, StatusFrame, h, SourceLength, StatusElHeight, TRUE); - MoveWindow(hwAnalyse, - cx - 3 * StatusFrame - QuitButtonLength - AnalyseLength - 20, - h, AnalyseLength, StatusElHeight, TRUE); - MoveWindow(hwQuitButton, - cx - StatusFrame - QuitButtonLength - 20, - h, QuitButtonLength, StatusElHeight, TRUE); + h = cy - LineHeight + StatusFrame - 2; + int statbegin = 3 * StatusFrame + QuitButtonLength + AnalyseLength + 4; + MoveWindow(hwSource, StatusFrame, h, cx - statbegin - BorderSize, StatusElHeight, TRUE); + MoveWindow( hwAnalyse, cx - statbegin, h, AnalyseLength, StatusElHeight, TRUE); + MoveWindow( hwQuitButton, cx - StatusFrame - QuitButtonLength - 1, + h + 1, QuitButtonLength, StatusElHeight, TRUE); } @@ -504,7 +550,11 @@ MainWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) default: DEFAULT_AFTER: +#ifdef EXT_ASC return DefWindowProc(hwnd, uMsg, wParam, lParam); +#else + return DefWindowProcW(hwnd, uMsg, wParam, lParam); +#endif } } @@ -518,18 +568,37 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) switch (uMsg) { case WM_CREATE: /* Get access to history information */ +#ifdef EXT_ASC pp_hi = (struct History_info **) ((LPCREATESTRUCT) lParam)->lpCreateParams; +#else + pp_hi = (struct History_info **) + ((LPCREATESTRUCTW) lParam)->lpCreateParams; +#endif break; case WM_KEYDOWN: { const UINT i = (UINT) wParam; if ((i == VK_UP) || (i == VK_DOWN)) { /* Set old text to new */ +#ifdef EXT_ASC SetWindowText(hwnd, (i == VK_UP) ? history_get_prev(*pp_hi, NULL) : history_get_next(*pp_hi, NULL)); /* Put cursor to end of line */ CallWindowProc(swProc, hwnd, uMsg, (WPARAM) VK_END, lParam); +#else + const char *newtext = (i == VK_UP) ? + history_get_prev(*pp_hi, NULL) : + history_get_next(*pp_hi, NULL); + wchar_t *newtextW; + newtextW = TMALLOC(wchar_t, 2 * strlen(newtext) + 1); + MultiByteToWideChar( + CP_UTF8, 0, newtext, -1, newtextW, 2 * (int) strlen(newtext) + 1); + SetWindowTextW(swString, newtextW); + tfree(newtextW); + /* Put cursor to end of line */ + CallWindowProcW(swProc, hwnd, uMsg, (WPARAM) VK_END, lParam); +#endif return 0; } if (i == VK_ESCAPE) { @@ -547,8 +616,19 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) * buffer for writing the string + NULL. The NULL will be * overwritten by the strcpy below, so it should not be * counted in the size needed for the CRLF string. */ +#ifdef EXT_ASC const int n_char_returned = GetWindowText( hwnd, SBuffer, sizeof SBuffer - (sizeof CRLF - 1)); +#else + wchar_t *WBuffer = TMALLOC(wchar_t, sizeof(SBuffer)); + /* for utf-8 the number of characters is not the number of bytes returned */ + GetWindowTextW(hwnd, WBuffer, sizeof SBuffer - (sizeof CRLF - 1)); + WideCharToMultiByte(CP_UTF8, 0, WBuffer, + -1, SBuffer, sizeof SBuffer - 1, NULL, NULL); + /* retrive here the number of bytes returned */ + const int n_char_returned = (int)strlen(SBuffer); + tfree(WBuffer); +#endif unsigned int n_char_prev_cmd; /* Add the command to the history if it is different from the @@ -566,8 +646,7 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } else { history_reset_pos(*pp_hi); - } - + } strcpy(SBuffer + n_char_returned, CRLF); ClearInput(); @@ -592,7 +671,11 @@ StringWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } /* end of switch over handled messages */ /* Fowrard to be processed further by swProc */ - return CallWindowProc(swProc, hwnd, uMsg, wParam, lParam); +#ifdef EXT_ASC + return CallWindowProc(swProc, hwnd, uMsg, wParam, lParam); +#else + return CallWindowProcW( swProc, hwnd, uMsg, wParam, lParam); +#endif } @@ -628,7 +711,11 @@ TextWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } default: DEFAULT_TEXT: +#ifdef EXT_ASC return CallWindowProc(twProc, hwnd, uMsg, wParam, lParam); +#else + return CallWindowProcW( twProc, hwnd, uMsg, wParam, lParam); +#endif } } @@ -640,7 +727,11 @@ Element_OnPaint(HWND hwnd) RECT r; RECT s; HGDIOBJ o; +#ifdef EXT_ASC char buffer[128]; +#else + wchar_t bufferW[256]; +#endif int i; /* Prepare */ @@ -669,6 +760,7 @@ Element_OnPaint(HWND hwnd) FillRect(hdc, &s, o); /* Draw contents */ +#ifdef EXT_ASC buffer[0] = '\0'; i = GetWindowText(hwnd, buffer, 127); s.left = r.left + 1; @@ -679,7 +771,19 @@ Element_OnPaint(HWND hwnd) FillRect(hdc, &s, o); SetBkMode(hdc, TRANSPARENT); ExtTextOut(hdc, s.left + 1, s.top + 1, ETO_CLIPPED, &s, buffer, (unsigned)i, NULL); - +#else + bufferW[0] = '\0'; + i = GetWindowTextW(hwnd, bufferW, 255); + s.left = r.left + 1; + s.right = r.right - 1; + s.top = r.top + 1; + s.bottom = r.bottom - 1; + o = GetSysColorBrush(COLOR_BTNFACE); + FillRect(hdc, &s, o); + SetBkMode(hdc, TRANSPARENT); + SelectObject(hdc, efont); + ExtTextOutW(hdc, s.left + 1, s.top + 1, ETO_CLIPPED, &s, bufferW, (unsigned)i, NULL); +#endif /* End */ EndPaint(hwnd, &ps); } @@ -696,7 +800,11 @@ ElementWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; default: +#ifdef EXT_ASC return DefWindowProc(hwnd, uMsg, wParam, lParam); +#else + return DefWindowProcW( hwnd, uMsg, wParam, lParam); +#endif } } @@ -850,9 +958,16 @@ MakeArgcArgv(char *cmdline, int *argc, char ***argv) /* Main entry point for our Windows application */ +#ifdef EXT_ASC int WINAPI -WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, - _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) +WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpszCmdLine, _In_ int nCmdShow) +#elif __MINGW32__ /* MINGW bug not knowing wWinMain */ +int WINAPI +WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR nolpszCmdLine, _In_ int nCmdShow) +#else +int WINAPI +wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR wlpszCmdLine, _In_ int nCmdShow) +#endif { int ix, iy; /* width and height of screen */ int status; @@ -871,6 +986,38 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, NG_IGNORE(hPrevInstance); +#ifndef EXT_ASC + /* convert wchar to utf-8 */ + + /* MINGW not knowing wWinMain + https://github.com/coderforlife/mingw-unicode-main/blob/master/mingw-unicode-gui.c + */ +#ifdef __MINGW32__ + NG_IGNORE(nolpszCmdLine); + char lpszCmdLine[1024]; + wchar_t *lpCmdLine = GetCommandLineW(); + if (__argc == 1) { // avoids GetCommandLineW bug that does not always quote the program name if no arguments + do { ++lpCmdLine; } while (*lpCmdLine); + } + else { + BOOL quoted = lpCmdLine[0] == L'"'; + ++lpCmdLine; // skips the " or the first letter (all paths are at least 1 letter) + while (*lpCmdLine) { + if (quoted && lpCmdLine[0] == L'"') { quoted = FALSE; } // found end quote + else if (!quoted && lpCmdLine[0] == L' ') { + // found an unquoted space, now skip all spaces + do { ++lpCmdLine; } while (lpCmdLine[0] == L' '); + break; + } + ++lpCmdLine; + } + } + WideCharToMultiByte(CP_UTF8, 0, lpCmdLine, -1, lpszCmdLine, 1023, NULL, NULL); +#else + char lpszCmdLine[1024]; + WideCharToMultiByte(CP_UTF8, 0, wlpszCmdLine, -1, lpszCmdLine, 1023, NULL, NULL); +#endif +#endif /* fill global variables */ hInst = hInstance; nShowState = nCmdShow; @@ -881,6 +1028,7 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, SBuffer[0] = SE; /* Define main window class */ +#ifdef EXT_ASC hwMainClass.style = CS_HREDRAW | CS_VREDRAW; hwMainClass.lpfnWndProc = MainWindowProc; hwMainClass.cbClsExtra = 0; @@ -894,8 +1042,23 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, if (!RegisterClass(&hwMainClass)) goto THE_END; +#else + hwMainClassW.style = CS_HREDRAW | CS_VREDRAW; + hwMainClassW.lpfnWndProc = MainWindowProc; + hwMainClassW.cbClsExtra = 0; + hwMainClassW.cbWndExtra = 0; + hwMainClassW.hInstance = hInst; + hwMainClassW.hIcon = LoadIconW(hInst, MAKEINTRESOURCEW(1)); + hwMainClassW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512)); + hwMainClassW.hbrBackground = GetStockObject(LTGRAY_BRUSH); + hwMainClassW.lpszMenuName = NULL; + hwMainClassW.lpszClassName = hwClassNameW; + if (!RegisterClassW(&hwMainClassW)) + goto THE_END; +#endif /* Define text window class */ +#ifdef EXT_ASC if (!GetClassInfo(NULL, "EDIT", &twTextClass)) goto THE_END; @@ -907,8 +1070,19 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, if (!RegisterClass(&twTextClass)) goto THE_END; +#else + if (!GetClassInfoW(NULL, L"EDIT", &twTextClassW)) goto THE_END; + twProc = twTextClassW.lpfnWndProc; + twTextClassW.lpfnWndProc = TextWindowProc; + twTextClassW.hInstance = hInst; + twTextClassW.lpszMenuName = NULL; + twTextClassW.lpszClassName = twClassNameW; + if (!RegisterClassW(&twTextClassW)) + goto THE_END; +#endif /* Define string window class */ +#ifdef EXT_ASC if (!GetClassInfo(NULL, "EDIT", &swStringClass)) goto THE_END; @@ -920,8 +1094,19 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, if (!RegisterClass(&swStringClass)) goto THE_END; +#else + if (!GetClassInfoW(NULL, L"EDIT", &swStringClassW)) goto THE_END; + swProc = swStringClassW.lpfnWndProc; + swStringClassW.lpfnWndProc = StringWindowProc; + swStringClassW.hInstance = hInst; + swStringClassW.lpszMenuName = NULL; + swStringClassW.lpszClassName = swClassNameW; + if (!RegisterClassW(&swStringClassW)) + goto THE_END; +#endif /* Define status element class */ +#ifdef EXT_ASC hwElementClass.style = CS_HREDRAW | CS_VREDRAW; hwElementClass.lpfnWndProc = ElementWindowProc; hwElementClass.cbClsExtra = 0; @@ -935,43 +1120,85 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, if (!RegisterClass(&hwElementClass)) goto THE_END; +#else + hwElementClassW.style = CS_HREDRAW | CS_VREDRAW; + hwElementClassW.lpfnWndProc = ElementWindowProc; + hwElementClassW.cbClsExtra = 0; + hwElementClassW.cbWndExtra = 0; + hwElementClassW.hInstance = hInst; + hwElementClassW.hIcon = NULL; + hwElementClassW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(32512)); + hwElementClassW.hbrBackground = GetStockObject(LTGRAY_BRUSH); + hwElementClassW.lpszMenuName = NULL; + hwElementClassW.lpszClassName = hwElementClassNameW; + if (!RegisterClassW(&hwElementClassW)) + goto THE_END; +#endif - /*Create main window */ -// iy = GetSystemMetrics(SM_CYSCREEN); -// iyt = GetSystemMetrics(SM_CYSCREEN) / 3; -// ix = GetSystemMetrics(SM_CXSCREEN); + /* Font for element status windows (source, analysis, Quit button) */ + efont = CreateFontW(16, 6, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + ANTIALIASED_QUALITY, VARIABLE_PITCH, L""); +/* efont = CreateFontW(16, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, + DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, VARIABLE_PITCH, L"Segoe UI");*/ +/* efont = CreateFontW(15, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, FALSE, + ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier");*/ + if (!efont) + efont = GetStockFont(ANSI_FIXED_FONT); + +#ifdef EXT_ASC SystemParametersInfo(SPI_GETWORKAREA, 0, &wsize, 0); +#else + SystemParametersInfoW(SPI_GETWORKAREA, 0, &wsize, 0); +#endif iy = wsize.bottom; ix = wsize.right; #ifndef BIG_WINDOW_FOR_DEBUGGING const int iyt = iy / 3; /* height of screen divided by 3 */ +#ifdef EXT_ASC hwMain = CreateWindow(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, - 0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL); + 0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL); #else + hwMain = CreateWindowW(hwClassNameW, hwWindowNameW, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + 0, iyt * 2, ix, iyt, NULL, NULL, hInst, NULL); +#endif +#else +#ifdef EXT_ASC hwMain = CreateWindow(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, 0, 0, ix, iy, NULL, NULL, hInst, NULL); +#else + hwMain = CreateWindowW(hwClassName, hwWindowName, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + 0, 0, ix, iy, NULL, NULL, hInst, NULL); +#endif #endif if (!hwMain) goto THE_END; /* Create text window */ +#ifdef EXT_ASC twText = CreateWindowEx(WS_EX_NOPARENTNOTIFY, twClassName, twWindowName, ES_LEFT | ES_MULTILINE | ES_READONLY | WS_CHILD | WS_BORDER | WS_VSCROLL, 20, 20, 300, 100, hwMain, NULL, hInst, NULL); +#else + twText = CreateWindowExW(WS_EX_NOPARENTNOTIFY, twClassNameW, twWindowNameW, + ES_LEFT | ES_MULTILINE | ES_READONLY | WS_CHILD | WS_BORDER | WS_VSCROLL, + 20,20,300,100, hwMain, NULL, hInst, NULL); +#endif if (!twText) goto THE_END; - /* Ansii fixed font */ +#ifdef EXT_ASC { HDC textDC; - HFONT font; TEXTMETRIC tm; - font = GetStockFont(ANSI_FIXED_FONT); - SetWindowFont(twText, font, FALSE); + tfont = GetStockFont(ANSI_FIXED_FONT); + SetWindowFont(twText, tfont, FALSE); textDC = GetDC(twText); if (textDC) { - SelectObject(textDC, font); + SelectObject(textDC, tfont); if (GetTextMetrics(textDC, &tm)) { RowHeight = tm.tmHeight; WinLineWidth = 90 * tm.tmAveCharWidth; @@ -979,9 +1206,39 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, ReleaseDC(twText, textDC); } } +#else + { + HDC textDC; + TEXTMETRICW tm; + tfont = CreateFontW(15, 0, 0, 0, FW_MEDIUM, FALSE, FALSE, + FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + NONANTIALIASED_QUALITY, FIXED_PITCH | FF_MODERN, L"Courier"); + /* Ansi fixed font */ + if(!tfont) + tfont = GetStockFont(ANSI_FIXED_FONT); + SetWindowFont( twText, tfont, FALSE); + textDC = GetDC( twText); + if (textDC) { + SelectObject( textDC, tfont); + if (GetTextMetricsW( textDC, &tm)) { + RowHeight = tm.tmHeight; + WinLineWidth = 90 * tm.tmAveCharWidth; + } + ReleaseDC( twText, textDC); + } + } +#endif /* Create string window for input. Give a handle to history info to * the window for saving and retrieving commands */ + /* Font for element status windows (source, analysis) */ + sfont = CreateFontW(16, 0, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, + DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + ANTIALIASED_QUALITY, VARIABLE_PITCH, L""); + /* Ansi fixed font */ + if(!sfont) + sfont = GetStockFont(ANSI_FIXED_FONT); +#ifdef EXT_ASC swString = CreateWindowEx(WS_EX_NOPARENTNOTIFY, swClassName, swWindowName, ES_LEFT | WS_CHILD | WS_BORDER | ES_AUTOHSCROLL, /* Allow text to scroll */ @@ -999,30 +1256,77 @@ WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, LineHeight = tm.tmHeight + tm.tmExternalLeading + BorderSize; ReleaseDC(swString, stringDC); } - } + } +#else + swString = CreateWindowExW(WS_EX_NOPARENTNOTIFY, swClassNameW, swWindowNameW, + ES_LEFT | WS_CHILD | WS_BORDER | + ES_AUTOHSCROLL, /* Allow text to scroll */ + 20, 20, 300, 100, hwMain, NULL, hInst, &p_hi); + if (!swString) + goto THE_END; + { + HDC stringDC; + TEXTMETRICW tm; + stringDC = GetDC(swString); + if (stringDC) { + SelectObject(stringDC, sfont); + if (GetTextMetricsW(stringDC, &tm)) + LineHeight = tm.tmHeight + tm.tmExternalLeading + BorderSize; + ReleaseDC(swString, stringDC); + } + } +#endif + /* Element windows */ /* Create source window */ +#ifdef EXT_ASC hwSource = CreateWindowEx(WS_EX_NOPARENTNOTIFY, hwElementClassName, hwSourceWindowName, WS_CHILD, 0, 0, SourceLength, StatusElHeight, hwMain, NULL, hInst, NULL); +#else + hwSource = CreateWindowExW(WS_EX_NOPARENTNOTIFY, hwElementClassNameW, hwSourceWindowNameW, + WS_CHILD, + 0, 0, SourceLength, StatusElHeight, hwMain, NULL, hInst, NULL); +#endif if (!hwSource) goto THE_END; + SetWindowFont(hwSource, efont, FALSE); /* Create analysis window */ +#ifdef EXT_ASC hwAnalyse = CreateWindowEx(WS_EX_NOPARENTNOTIFY, hwElementClassName, hwAnalyseWindowName, WS_CHILD, 0, 0, AnalyseLength, StatusElHeight, hwMain, NULL, hInst, NULL); +#else + hwAnalyse = CreateWindowExW(WS_EX_NOPARENTNOTIFY, hwElementClassNameW, hwAnalyseWindowNameW, + WS_CHILD, + 0,0, AnalyseLength, StatusElHeight, hwMain, NULL, hInst, NULL); +#endif if (!hwAnalyse) goto THE_END; + SetWindowFont(hwAnalyse, efont, FALSE); + /* Create "Quit" button */ +#ifdef EXT_ASC hwQuitButton = CreateWindow("BUTTON", "Quit", WS_CHILD | BS_PUSHBUTTON, 0, 0, QuitButtonLength, StatusElHeight, hwMain, (HMENU)(UINT_PTR)QUIT_BUTTON_ID, hInst, NULL); +#else + hwQuitButton = CreateWindowW(L"BUTTON", L"Quit", WS_CHILD | BS_PUSHBUTTON, 0, 0, QuitButtonLength, + StatusElHeight, hwMain, (HMENU)(UINT_PTR)QUIT_BUTTON_ID, hInst, NULL); +#endif if (!hwQuitButton) goto THE_END; + SetWindowFont(hwQuitButton, efont, FALSE); + + /* Define a minimum width */ + int MinWidth = AnalyseLength + SourceLength + QuitButtonLength + 48; + if (WinLineWidth < MinWidth) + WinLineWidth = MinWidth; + /* Make main window and subwindows visible. Size of windows allows display of 80 character line. Limit window to screen size (if only VGA). */ diff --git a/src/xspice/icm/digital/d_state/cfunc.mod b/src/xspice/icm/digital/d_state/cfunc.mod index 5f5248589..778778623 100644 --- a/src/xspice/icm/digital/d_state/cfunc.mod +++ b/src/xspice/icm/digital/d_state/cfunc.mod @@ -1891,7 +1891,9 @@ void cm_d_state(ARGS) LOAD(clk) = PARAM(clk_load); - LOAD(reset) = PARAM(reset_load); + if ( !PORT_NULL(reset) ) { + LOAD(reset) = PARAM(reset_load); + } } else { /**** Retrieve previous values ****/ diff --git a/src/xspice/icm/table/table3D/cfunc.mod b/src/xspice/icm/table/table3D/cfunc.mod index 56f145fdb..411cc8fd8 100644 --- a/src/xspice/icm/table/table3D/cfunc.mod +++ b/src/xspice/icm/table/table3D/cfunc.mod @@ -418,6 +418,7 @@ static Table3_Data_t *init_local_data(const char *filename, int interporder) lFileRead = fread(cFile, sizeof(char), lFileLen, fp); const int file_error = ferror(fp); fclose(fp); /* done with file */ + fp = (FILE *) NULL; if (file_error) { cm_message_printf("Error reading data file %s", filename); xrc = -1; diff --git a/visualc/src/include/ngspice/config.h b/visualc/src/include/ngspice/config.h index 31034f571..983d1b037 100644 --- a/visualc/src/include/ngspice/config.h +++ b/visualc/src/include/ngspice/config.h @@ -551,3 +551,7 @@ /* Define as `fork' if `vfork' does not work. */ #define vfork fork + +#define HAVE_XFT + +//#define EXT_ASC diff --git a/visualc/vngspice-fftw.vcxproj b/visualc/vngspice-fftw.vcxproj index b60c10eef..e197090a0 100644 --- a/visualc/vngspice-fftw.vcxproj +++ b/visualc/vngspice-fftw.vcxproj @@ -1501,7 +1501,6 @@ lib /machine:x64 /def:..\..\fftw-3.3-dll64\libfftw3-3.def /out:$(IntDir)libfftw3 - diff --git a/visualc/vngspice.vcxproj b/visualc/vngspice.vcxproj index ebba7daa0..b92489816 100644 --- a/visualc/vngspice.vcxproj +++ b/visualc/vngspice.vcxproj @@ -906,7 +906,6 @@ - @@ -922,6 +921,7 @@ + @@ -940,6 +940,7 @@ + @@ -1509,7 +1510,6 @@ - @@ -1531,6 +1531,7 @@ +