mirror of https://github.com/KLayout/klayout.git
Merge branch 'master' into xor-performance
This commit is contained in:
commit
1c836de07e
23
Changelog
23
Changelog
|
|
@ -1,3 +1,26 @@
|
|||
0.28.17 (2024-02-16):
|
||||
* Enhancement: %GITHUB%/issues/1626 Technology specific grids
|
||||
|
||||
0.28.16 (2024-02-12):
|
||||
* Bugfix: %GITHUB%/issues/1623 Package installation with "-y" from command line does not work for URL or file
|
||||
* Bugfix: %GITHUB%/issues/1619 Segfault on Fedora-39 with Python 3.12.1
|
||||
* Bugfix: %GITHUB%/issues/1618 Leaking Python reference causing trouble with iterators
|
||||
* Bugfix: %GITHUB%/issues/1616 DRC doc typo
|
||||
* Bugfix: %GITHUB%/issues/1614 LEF/DEF .map should not map boundaries and fill to ALL purpose
|
||||
* Bugfix: %GITHUB%/issues/1609 Cell.read doesn't read LayoutMetaInfo
|
||||
* Bugfix: %GITHUB%/issues/1608 CustomResistorExtraction: show faulty device in GUI
|
||||
* Bugfix: %GITHUB%/issues/1603 Weird parameter dialog resizing when hiding / showing many parameters at once with callback_impl
|
||||
* Bugfix: %GITHUB%/issues/1602 [Qt6] Cannot normally quit the main application window
|
||||
* Bugfix: %GITHUB%/issues/1594 "connect" (in flat mode) + multiple top cells give an error message
|
||||
* Bugfix: %GITHUB%/issues/1592 DXF file parsing error, about spline curve
|
||||
* Enhancement: DRC enhancements related to touching edges
|
||||
- New DRC function switches: "without_touching_corners", "without_touching_edges"
|
||||
to skip width and space errors at kissing corners and touching-edge configurations
|
||||
- Kissing corners are now detected also in non-collinear edge configurations
|
||||
* Bugfix: fixed rendering of color selection buttons on High-DPI screens
|
||||
* Bugfix: cross-hair cursor should not use selection default line width and styles
|
||||
* Enhancement: OASIS reader errors out on broken OASIS with duplicate CELLNAMEs
|
||||
|
||||
0.28.15 (2024-01-04):
|
||||
* Bugfix: %GITHUB%/issues/1578 Missing strm2*.exe in the Windows portable binary package (*.zip)
|
||||
* Enhancement: %GITHUB%/issues/1569 Make "toggle (selected) layer" key-bindable
|
||||
|
|
|
|||
|
|
@ -1,3 +1,17 @@
|
|||
klayout (0.28.17-1) unstable; urgency=low
|
||||
|
||||
* New features and bugfixes
|
||||
- See changelog
|
||||
|
||||
-- Matthias Köfferlein <matthias@koefferlein.de> Fri, 16 Feb 2024 15:52:09 +0100
|
||||
|
||||
klayout (0.28.16-1) unstable; urgency=low
|
||||
|
||||
* New features and bugfixes
|
||||
- See changelog
|
||||
|
||||
-- Matthias Köfferlein <matthias@koefferlein.de> Mon, 12 Feb 2024 00:00:00 +0100
|
||||
|
||||
klayout (0.28.15-1) unstable; urgency=low
|
||||
|
||||
* New features and bugfixes
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
Relevant KLayout version: 0.28.15<br>
|
||||
Relevant KLayout version: 0.28.17<br>
|
||||
Author: Kazzz-S<br>
|
||||
Last modified: 2024-01-05<br>
|
||||
Last modified: 2024-02-16<br>
|
||||
|
||||
# 1. Introduction
|
||||
This directory **`macbuild`** contains various files required for building KLayout (http://www.klayout.de/) version 0.28.13 or later for different 64-bit macOS, including:
|
||||
This directory **`macbuild`** contains various files required for building KLayout (http://www.klayout.de/) version 0.28.17 or later for different 64-bit macOS, including:
|
||||
* Monterey (12.x) : the primary development environment
|
||||
* Ventura (13.x) : experimental
|
||||
* Sonoma (14.x) : -- ditto --
|
||||
|
|
@ -51,6 +51,8 @@ Some typical use cases are described in Section 6.
|
|||
# 4. Prerequisites
|
||||
You need to have the followings:
|
||||
* The latest Xcode and command-line tool kit compliant with each OS
|
||||
* https://developer.apple.com/xcode/resources/
|
||||
* https://mac.install.guide/commandlinetools/4
|
||||
* Qt5 package from Homebrew, MacPorts, or Anaconda3
|
||||
* Optionally, Ruby and Python packages from Homebrew, MacPorts, or Anaconda3
|
||||
#### For matching versions of Ruby and Python, please also refer to `build4mac_env.py`.
|
||||
|
|
@ -63,12 +65,12 @@ The operating system type is detected automatically.
|
|||
```
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
<< Usage of 'build4mac.py' >>
|
||||
for building KLayout 0.28.13 or later on different Apple macOS platforms.
|
||||
for building KLayout 0.28.17 or later on different Apple macOS platforms.
|
||||
|
||||
$ [python] ./build4mac.py
|
||||
option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value
|
||||
--------------------------------------------------------------------------------------+---------------
|
||||
[-q|--qt <type>] : case-insensitive type=['Qt5MacPorts', 'Qt5Brew', 'Qt5Ana3', | qt5brew
|
||||
[-q|--qt <type>] : case-insensitive type=['Qt5MacPorts', 'Qt5Brew', 'Qt5Ana3', | qt5macports
|
||||
: 'Qt6MacPorts', 'Qt6Brew'] |
|
||||
: Qt5MacPorts: use Qt5 from MacPorts |
|
||||
: Qt5Brew: use Qt5 from Homebrew |
|
||||
|
|
@ -76,20 +78,21 @@ $ [python] ./build4mac.py
|
|||
: Qt6MacPorts: use Qt6 from MacPorts (*) |
|
||||
: Qt6Brew: use Qt6 from Homebrew (*) |
|
||||
: (*) migration to Qt6 is ongoing |
|
||||
[-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP32', 'HB32', 'Ana3'] | hb32
|
||||
[-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP33', 'HB33', 'Ana3'] | sys
|
||||
: nil: don't bind Ruby |
|
||||
: Sys: use [Sonoma|Ventura|Monterey]-bundled Ruby 2.6 |
|
||||
: MP32: use Ruby 3.2 from MacPorts |
|
||||
: HB32: use Ruby 3.2 from Homebrew |
|
||||
: MP33: use Ruby 3.3 from MacPorts |
|
||||
: HB33: use Ruby 3.3 from Homebrew |
|
||||
: Ana3: use Ruby 3.2 from Anaconda3 |
|
||||
[-p|--python <type>] : case-insensitive type=['nil', 'MP311', 'HB311', 'Ana3', | hb311
|
||||
: 'MP39', 'hb311', 'HBAuto'] |
|
||||
[-p|--python <type>] : case-insensitive type=['nil', 'Sys', 'MP311', 'HB311', 'Ana3', | sys
|
||||
: 'MP39', 'HB39', 'HBAuto'] |
|
||||
: nil: don't bind Python |
|
||||
: Sys: use [Sonoma|Ventura|Monterey]-bundled Python 3.9 |
|
||||
: MP311: use Python 3.11 from MacPorts |
|
||||
: HB311: use Python 3.11 from Homebrew |
|
||||
: Ana3: use Python 3.11 from Anaconda3 |
|
||||
: MP39: use Python 3.9 from MacPorts (+) |
|
||||
: hb311: use Python 3.9 from Homebrew (+) |
|
||||
: HB39: use Python 3.9 from Homebrew (+) |
|
||||
: (+) for the backward compatibility tests |
|
||||
: HBAuto: use the latest Python 3.x auto-detected from Homebrew |
|
||||
[-P|--buildPymod] : build and deploy Pymod (*.whl) for LW-*.dmg | disabled
|
||||
|
|
@ -118,24 +121,55 @@ $ [python] ./build4mac.py
|
|||
In this section, the actual file and directory names are those obtained on macOS Monterey.<br>
|
||||
On different OS, those names differ accordingly.
|
||||
|
||||
### 6A. Standard build using the OS-bundled Ruby and Python with MacPorts
|
||||
This build has been discontinued.
|
||||
### 6A. Standard build using the OS-bundled Ruby and Python with MacPorts Qt
|
||||
0. Install MacPorts, then install Qt5 and libgit2 by
|
||||
```
|
||||
$ sudo port install coreutils
|
||||
$ sudo port install findutils
|
||||
$ sudo port install qt5
|
||||
$ sudo port install libgit2
|
||||
```
|
||||
|
||||
### 6B. Fully Homebrew-flavored build with Homebrew Ruby 3.2 and Homebrew Python 3.11
|
||||
0. Install Homebrew, then install Qt5, Ruby 3.2, Python 3.11, and libgit2 by
|
||||
Confirm that you have:
|
||||
```
|
||||
/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/*
|
||||
```
|
||||
As of this writing, the provided Python version is `3.9.6`.
|
||||
|
||||
1. Invoke **`build4mac.py`** with the following options: **((Notes))** These options are the default values for Monterey, Ventura, and Sonoma.
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./build4mac.py -q qt5macports -r sys -p sys
|
||||
```
|
||||
2. Confirm successful build (it will take about one hour, depending on your machine spec).
|
||||
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
|
||||
The buddy command-line tools (strm*) will also be deployed under **klayout.app/Contents/Buddy/** in this step.<br>
|
||||
|
||||
```
|
||||
$ ./build4mac.py -q qt5macports -r sys -p sys -y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`ST-qt5MP.pkg.macos-Monterey-release-RsysPsys`** directory, where
|
||||
* "ST-" means this is a standard package.
|
||||
* "qt5MP" means that Qt5 from MacPorts is used.
|
||||
* "RsysPsys" means that Ruby is 2.6 provided by OS; Python is 3.9 provided by OS.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
|
||||
### 6B. Fully Homebrew-flavored build with Homebrew Ruby 3.3 and Homebrew Python 3.11
|
||||
0. Install Homebrew, then install Qt5, Ruby 3.3, Python 3.11, and libgit2 by
|
||||
```
|
||||
$ brew install qt@5
|
||||
$ brew install ruby@3.2
|
||||
$ brew install ruby@3.3
|
||||
$ brew install python@3.11
|
||||
$ brew install libgit2
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ cd macbuild
|
||||
$ ./python3HB.py -v 3.11
|
||||
```
|
||||
1. Invoke **`build4mac.py`** with the following options: **((Notes))** These options are the default values for Monterey, Ventura, and Sonoma.
|
||||
1. Invoke **`build4mac.py`** with the following options:
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./build4mac.py -q qt5brew -r hb32 -p hb311
|
||||
$ ./build4mac.py -q qt5brew -r hb33 -p hb311
|
||||
```
|
||||
2. Confirm successful build (it will take about one hour, depending on your machine spec).
|
||||
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
|
||||
|
|
@ -143,13 +177,13 @@ $ ./build4mac.py -q qt5brew -r hb32 -p hb311
|
|||
If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
|
||||
|
||||
```
|
||||
$ ./build4mac.py -q qt5brew -r hb32 -p hb311 -Y
|
||||
$ ./build4mac.py -q qt5brew -r hb33 -p hb311 -Y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`LW-qt5Brew.pkg.macos-Monterey-release-Rhb32Phb311`** directory, where
|
||||
**`LW-qt5Brew.pkg.macos-Monterey-release-Rhb33Phb311`** directory, where
|
||||
* "LW-" means this is a lightweight package.
|
||||
* "qt5Brew" means that Qt5 from Homebrew is used.
|
||||
* "Rhb32Phb311" means that Ruby is 3.2 from Homebrew; Python is 3.11 from Homebrew.
|
||||
* "Rhb33Phb311" means that Ruby is 3.3 from Homebrew; Python is 3.11 from Homebrew.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
|
||||
### 6C. Partially Homebrew-flavored build with System Ruby and Homebrew Python 3.11
|
||||
|
|
@ -184,13 +218,13 @@ $ ./build4mac.py -q qt5brew -r sys -p hb311 -y
|
|||
So far, the deployment of Homebrew Ruby is not supported.<br>
|
||||
Therefore, if you intend to use the "-y" option for deployment, you need to use the "-r sys" option for building.
|
||||
|
||||
### 6D. Fully MacPorts-flavored build with MacPorts Ruby 3.2 and MacPorts Python 3.11
|
||||
0. Install MacPorts, then install Qt5, Ruby 3.2, Python 3.11, and libgit2 by
|
||||
### 6D. Fully MacPorts-flavored build with MacPorts Ruby 3.3 and MacPorts Python 3.11
|
||||
0. Install MacPorts, then install Qt5, Ruby 3.3, Python 3.11, and libgit2 by
|
||||
```
|
||||
$ sudo port install coreutils
|
||||
$ sudo port install findutils
|
||||
$ sudo port install qt5
|
||||
$ sudo port install ruby32
|
||||
$ sudo port install ruby33
|
||||
$ sudo port install python311
|
||||
$ sudo port install py311-pip
|
||||
$ sudo port install libgit2
|
||||
|
|
@ -198,7 +232,7 @@ $ sudo port install libgit2
|
|||
1. Invoke **`build4mac.py`** with the following options:
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./build4mac.py -q qt5macports -r mp32 -p mp311
|
||||
$ ./build4mac.py -q qt5macports -r mp33 -p mp311
|
||||
```
|
||||
2. Confirm successful build (it will take about one hour, depending on your machine spec).
|
||||
3. Rerun **`build4mac.py`** with the same options used in 1. PLUS "-Y" to deploy executables and libraries under **`klayout.app`** bundle.<br>
|
||||
|
|
@ -206,13 +240,13 @@ $ ./build4mac.py -q qt5macports -r mp32 -p mp311
|
|||
If you use `--buildPymod` option in Step-1 and Step-3, the KLayout Python Module (\*.whl) will be built and deployed under **klayout.app/Contents/pymod-dist/**.
|
||||
|
||||
```
|
||||
$ ./build4mac.py -q qt5macports -r mp32 -p mp311 -Y
|
||||
$ ./build4mac.py -q qt5macports -r mp33 -p mp311 -Y
|
||||
```
|
||||
The application bundle **`klayout.app`** is located under:<br>
|
||||
**`LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311`** directory, where
|
||||
**`LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311`** directory, where
|
||||
* "LW-" means this is a lightweight package.
|
||||
* "qt5MP" means that Qt5 from MacPorts is used.
|
||||
* "Rmp32Pmp311" means that Ruby is 3.2 from MacPorts; Python is 3.11 from MacPorts.
|
||||
* "Rmp33Pmp311" means that Ruby is 3.3 from MacPorts; Python is 3.11 from MacPorts.
|
||||
4. Copy/move the generated application bundle **`klayout.app`** to your **`/Applications`** directory for installation.
|
||||
|
||||
### 6E. Fully Anaconda3-flavored build with Anaconda3 Ruby 3.2 and Anaconda3 Python 3.11
|
||||
|
|
@ -273,11 +307,11 @@ makeDMG4mac.py -> macbuild/makeDMG4mac.py
|
|||
2. Invoke **`makeDMG4mac.py`** with -p and -m options, for example,
|
||||
```
|
||||
$ cd /where/'build.sh'/exists
|
||||
$ ./makeDMG4mac.py -p LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311 -m
|
||||
$ ./makeDMG4mac.py -p LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311 -m
|
||||
```
|
||||
This command will generate the two files below:<br>
|
||||
* **`LW-klayout-0.28.13-macOS-Monterey-1-qt5MP-Rmp32Pmp311.dmg`** ---(1) the main DMG file
|
||||
* **`LW-klayout-0.28.13-macOS-Monterey-1-qt5MP-Rmp32Pmp311.dmg.md5`** ---(2) MD5-value text file
|
||||
* **`LW-klayout-0.28.17-macOS-Monterey-1-qt5MP-Rmp33Pmp311.dmg`** ---(1) the main DMG file
|
||||
* **`LW-klayout-0.28.17-macOS-Monterey-1-qt5MP-Rmp33Pmp311.dmg.md5`** ---(2) MD5-value text file
|
||||
|
||||
# Known issues
|
||||
Because we assume some specific versions of non-OS-standard Ruby and Python, updating Homebrew, MacPorts, or Anaconda3 may cause build- and link errors.<br>
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -5,7 +5,7 @@
|
|||
# File: "macbuild/build4mac.py"
|
||||
#
|
||||
# The top Python script for building KLayout (http://www.klayout.de/index.php)
|
||||
# version 0.28.13 or later on different Apple Mac OSX platforms.
|
||||
# version 0.28.17 or later on different Apple Mac OSX platforms.
|
||||
#===============================================================================
|
||||
import sys
|
||||
import os
|
||||
|
|
@ -35,17 +35,17 @@ from build4mac_util import *
|
|||
#-------------------------------------------------------------------------------
|
||||
def GenerateUsage(platform):
|
||||
if platform.upper() in [ "SONOMA", "VENTURA", "MONTEREY" ]: # with Xcode [13.1 .. ]
|
||||
myQt56 = "qt5brew"
|
||||
myRuby = "hb32"
|
||||
myPython = "hb311"
|
||||
moduleset = ('qt5Brew', 'HB32', 'HB311')
|
||||
myQt56 = "qt5macports"
|
||||
myRuby = "sys"
|
||||
myPython = "sys"
|
||||
moduleset = ('Qt5MacPorts', 'Sys', 'Sys')
|
||||
else: # too obsolete
|
||||
raise Exception( "! Too obsolete platform <%s>" % platform )
|
||||
|
||||
usage = "\n"
|
||||
usage += "---------------------------------------------------------------------------------------------------------\n"
|
||||
usage += "<< Usage of 'build4mac.py' >>\n"
|
||||
usage += " for building KLayout 0.28.13 or later on different Apple macOS platforms.\n"
|
||||
usage += " for building KLayout 0.28.17 or later on different Apple macOS platforms.\n"
|
||||
usage += "\n"
|
||||
usage += "$ [python] ./build4mac.py\n"
|
||||
usage += " option & argument : descriptions (refer to 'macbuild/build4mac_env.py' for details)| default value\n"
|
||||
|
|
@ -58,15 +58,16 @@ def GenerateUsage(platform):
|
|||
usage += " : Qt6MacPorts: use Qt6 from MacPorts (*) |\n"
|
||||
usage += " : Qt6Brew: use Qt6 from Homebrew (*) |\n"
|
||||
usage += " : (*) migration to Qt6 is ongoing |\n"
|
||||
usage += " [-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP32', 'HB32', 'Ana3'] | %s\n" % myRuby
|
||||
usage += " [-r|--ruby <type>] : case-insensitive type=['nil', 'Sys', 'MP33', 'HB33', 'Ana3'] | %s\n" % myRuby
|
||||
usage += " : nil: don't bind Ruby |\n"
|
||||
usage += " : Sys: use [Sonoma|Ventura|Monterey]-bundled Ruby 2.6 |\n"
|
||||
usage += " : MP32: use Ruby 3.2 from MacPorts |\n"
|
||||
usage += " : HB32: use Ruby 3.2 from Homebrew |\n"
|
||||
usage += " : MP33: use Ruby 3.3 from MacPorts |\n"
|
||||
usage += " : HB33: use Ruby 3.3 from Homebrew |\n"
|
||||
usage += " : Ana3: use Ruby 3.2 from Anaconda3 |\n"
|
||||
usage += " [-p|--python <type>] : case-insensitive type=['nil', 'MP311', 'HB311', 'Ana3', | %s\n" % myPython
|
||||
usage += " [-p|--python <type>] : case-insensitive type=['nil', 'Sys', 'MP311', 'HB311', 'Ana3', | %s\n" % myPython
|
||||
usage += " : 'MP39', 'HB39', 'HBAuto'] |\n"
|
||||
usage += " : nil: don't bind Python |\n"
|
||||
usage += " : Sys: use [Sonoma|Ventura|Monterey]-bundled Python 3.9 |\n"
|
||||
usage += " : MP311: use Python 3.11 from MacPorts |\n"
|
||||
usage += " : HB311: use Python 3.11 from Homebrew |\n"
|
||||
usage += " : Ana3: use Python 3.11 from Anaconda3 |\n"
|
||||
|
|
@ -149,19 +150,19 @@ def Get_Default_Config():
|
|||
|
||||
# Set the default modules
|
||||
if Platform == "Sonoma":
|
||||
ModuleQt = "Qt5Brew"
|
||||
ModuleRuby = "Ruby32Brew"
|
||||
ModulePython = "Python311Brew"
|
||||
ModuleQt = "Qt5MacPorts"
|
||||
ModuleRuby = "Sys"
|
||||
ModulePython = "Sys"
|
||||
elif Platform == "Ventura":
|
||||
ModuleQt = "Qt5Brew"
|
||||
ModuleRuby = "Ruby32Brew"
|
||||
ModulePython = "Python311Brew"
|
||||
ModuleQt = "Qt5MacPorts"
|
||||
ModuleRuby = "Sys"
|
||||
ModulePython = "Sys"
|
||||
elif Platform == "Monterey":
|
||||
ModuleQt = "Qt5Brew"
|
||||
ModuleRuby = "Ruby32Brew"
|
||||
ModulePython = "Python311Brew"
|
||||
ModuleQt = "Qt5MacPorts"
|
||||
ModuleRuby = "Sys"
|
||||
ModulePython = "Sys"
|
||||
else:
|
||||
ModuleQt = "Qt5Brew"
|
||||
ModuleQt = "Qt5MacPorts"
|
||||
ModuleRuby = "nil"
|
||||
ModulePython = "nil"
|
||||
|
||||
|
|
@ -179,6 +180,7 @@ def Get_Default_Config():
|
|||
DeployVerbose = 1
|
||||
Version = GetKLayoutVersionFrom( "./version.sh" )
|
||||
HBPythonIs39 = False # because ModulePython == "Python311Brew" by default
|
||||
OSPython3FW = None # system Python3 frameworks in [ None, MontereyPy3FW, VenturaPy3FW, SonomaPy3FW ]
|
||||
|
||||
config = dict()
|
||||
config['ProjectDir'] = ProjectDir # project directory where "build.sh" exists
|
||||
|
|
@ -204,6 +206,7 @@ def Get_Default_Config():
|
|||
config['ModuleSet'] = ModuleSet # (Qt, Ruby, Python)-tuple
|
||||
config['ToolDebug'] = ToolDebug # debug level list for this tool
|
||||
config['HBPythonIs39'] = HBPythonIs39 # True if the Homebrew Python version <= 3.9
|
||||
config['OSPython3FW'] = OSPython3FW # system Python3 frameworks in [ None, MontereyPy3FW, VenturaPy3FW, SonomaPy3FW ]
|
||||
# auxiliary variables on platform
|
||||
config['System'] = System # 6-tuple from platform.uname()
|
||||
config['Node'] = Node # - do -
|
||||
|
|
@ -246,6 +249,7 @@ def Parse_CLI_Args(config):
|
|||
ModuleSet = config['ModuleSet']
|
||||
ToolDebug = config['ToolDebug']
|
||||
HBPythonIs39 = config['HBPythonIs39']
|
||||
OSPython3FW = config['OSPython3FW']
|
||||
|
||||
#-----------------------------------------------------
|
||||
# [2] Parse the CLI arguments
|
||||
|
|
@ -257,7 +261,7 @@ def Parse_CLI_Args(config):
|
|||
|
||||
p.add_option( '-r', '--ruby',
|
||||
dest='type_ruby',
|
||||
help="Ruby type=['nil', 'Sys', 'MP32', 'HB32', 'Ana3']" )
|
||||
help="Ruby type=['nil', 'Sys', 'MP33', 'HB33', 'Ana3']" )
|
||||
|
||||
p.add_option( '-p', '--python',
|
||||
dest='type_python',
|
||||
|
|
@ -331,9 +335,9 @@ def Parse_CLI_Args(config):
|
|||
help='check usage' )
|
||||
|
||||
if Platform.upper() in [ "SONOMA", "VENTURA", "MONTEREY" ]: # with Xcode [13.1 .. ]
|
||||
p.set_defaults( type_qt = "qt5brew",
|
||||
type_ruby = "hb32",
|
||||
type_python = "hb311",
|
||||
p.set_defaults( type_qt = "qt5macports",
|
||||
type_ruby = "sys",
|
||||
type_python = "sys",
|
||||
build_pymod = False,
|
||||
no_qt_binding = False,
|
||||
no_qt_uitools = False,
|
||||
|
|
@ -390,8 +394,8 @@ def Parse_CLI_Args(config):
|
|||
candidates = dict()
|
||||
candidates['NIL'] = 'nil'
|
||||
candidates['SYS'] = 'Sys'
|
||||
candidates['MP32'] = 'MP32'
|
||||
candidates['HB32'] = 'HB32'
|
||||
candidates['MP33'] = 'MP33'
|
||||
candidates['HB33'] = 'HB33'
|
||||
candidates['ANA3'] = 'Ana3'
|
||||
try:
|
||||
choiceRuby = candidates[ opt.type_ruby.upper() ]
|
||||
|
|
@ -403,18 +407,17 @@ def Parse_CLI_Args(config):
|
|||
if choiceRuby == "nil":
|
||||
ModuleRuby = 'nil'
|
||||
elif choiceRuby == "Sys":
|
||||
choiceRuby = "Sys"
|
||||
if Platform == "Sonoma":
|
||||
ModuleRuby = 'RubySonoma'
|
||||
elif Platform == "Ventura":
|
||||
ModuleRuby = 'RubyVentura'
|
||||
elif Platform == "Monterey":
|
||||
ModuleRuby = 'RubyMonterey'
|
||||
elif choiceRuby == "MP32":
|
||||
ModuleRuby = 'Ruby32MacPorts'
|
||||
elif choiceRuby == "MP33":
|
||||
ModuleRuby = 'Ruby33MacPorts'
|
||||
NonOSStdLang = True
|
||||
elif choiceRuby == "HB32":
|
||||
ModuleRuby = 'Ruby32Brew'
|
||||
elif choiceRuby == "HB33":
|
||||
ModuleRuby = 'Ruby33Brew'
|
||||
NonOSStdLang = True
|
||||
elif choiceRuby == "Ana3":
|
||||
ModuleRuby = 'RubyAnaconda3'
|
||||
|
|
@ -429,6 +432,7 @@ def Parse_CLI_Args(config):
|
|||
# (C) Determine the Python type
|
||||
candidates = dict()
|
||||
candidates['NIL'] = 'nil'
|
||||
candidates['SYS'] = 'Sys'
|
||||
candidates['MP311'] = 'MP311'
|
||||
candidates['HB311'] = 'HB311'
|
||||
candidates['ANA3'] = 'Ana3'
|
||||
|
|
@ -445,29 +449,49 @@ def Parse_CLI_Args(config):
|
|||
if choicePython == "nil":
|
||||
ModulePython = 'nil'
|
||||
HBPythonIs39 = None
|
||||
OSPython3FW = None
|
||||
elif choicePython == "Sys":
|
||||
if Platform == "Sonoma":
|
||||
ModulePython = 'PythonSonoma'
|
||||
HBPythonIs39 = None
|
||||
OSPython3FW = SonomaPy3FW
|
||||
elif Platform == "Ventura":
|
||||
ModulePython = 'PythonVentura'
|
||||
HBPythonIs39 = None
|
||||
OSPython3FW = VenturaPy3FW
|
||||
elif Platform == "Monterey":
|
||||
ModulePython = 'PythonMonterey'
|
||||
HBPythonIs39 = None
|
||||
OSPython3FW = MontereyPy3FW
|
||||
elif choicePython == "MP311":
|
||||
ModulePython = 'Python311MacPorts'
|
||||
HBPythonIs39 = None
|
||||
OSPython3FW = None
|
||||
NonOSStdLang = True
|
||||
elif choicePython == "HB311":
|
||||
ModulePython = 'Python311Brew'
|
||||
HBPythonIs39 = False
|
||||
OSPython3FW = None
|
||||
NonOSStdLang = True
|
||||
elif choicePython == "Ana3":
|
||||
ModulePython = 'PythonAnaconda3'
|
||||
HBPythonIs39 = None
|
||||
OSPython3FW = None
|
||||
NonOSStdLang = True
|
||||
elif choicePython == "MP39":
|
||||
ModulePython = 'Python39MacPorts'
|
||||
HBPythonIs39 = None
|
||||
OSPython3FW = None
|
||||
NonOSStdLang = True
|
||||
elif choicePython == "HB39":
|
||||
ModulePython = 'Python39Brew'
|
||||
HBPythonIs39 = True
|
||||
OSPython3FW = None
|
||||
NonOSStdLang = True
|
||||
elif choicePython == "HBAuto":
|
||||
ModulePython = 'PythonAutoBrew'
|
||||
HBPythonIs39 = (HBPythonAutoVersion == "3.9")
|
||||
OSPython3FW = None
|
||||
NonOSStdLang = True
|
||||
if ModulePython == '':
|
||||
print("")
|
||||
|
|
@ -524,7 +548,7 @@ def Parse_CLI_Args(config):
|
|||
else:
|
||||
message += "a lightweight (LW-) package with Pymod excluding Qt5, Ruby, and Python..."
|
||||
elif DeploymentF:
|
||||
if (ModuleRuby in RubySys) and (ModulePython in PythonSys): # won't meet this condition any more!
|
||||
if (ModuleRuby in RubySys) and (ModulePython in PythonSys):
|
||||
PackagePrefix = "ST-"
|
||||
message += "a standard (ST-) package including Qt[5|6] and using OS-bundled Ruby and Python..."
|
||||
elif ModulePython in ['Python311Brew', 'Python39Brew', 'PythonAutoBrew']:
|
||||
|
|
@ -568,6 +592,7 @@ def Parse_CLI_Args(config):
|
|||
config['ModuleSet'] = ModuleSet
|
||||
config['ToolDebug'] = ToolDebug
|
||||
config['HBPythonIs39'] = HBPythonIs39
|
||||
config['OSPython3FW'] = OSPython3FW
|
||||
|
||||
if CheckComOnly:
|
||||
pp = pprint.PrettyPrinter( indent=4, width=140 )
|
||||
|
|
@ -606,6 +631,7 @@ def Get_Build_Parameters(config):
|
|||
DeploymentF = config['DeploymentF']
|
||||
DeploymentP = config['DeploymentP']
|
||||
PackagePrefix = config['PackagePrefix']
|
||||
OSPython3FW = config['OSPython3FW']
|
||||
|
||||
#-----------------------------------------------------
|
||||
# [2] Set parameters passed to the main Bash script
|
||||
|
|
@ -652,7 +678,10 @@ def Get_Build_Parameters(config):
|
|||
|
||||
parameters['bin'] = MacBinDir
|
||||
parameters['build'] = MacBuildDir
|
||||
parameters['rpath'] = "@executable_path/../Frameworks"
|
||||
if OSPython3FW in [ MontereyPy3FW, VenturaPy3FW, SonomaPy3FW ]:
|
||||
parameters['rpath'] = OSPython3FW
|
||||
else:
|
||||
parameters['rpath'] = "@executable_path/../Frameworks"
|
||||
|
||||
# (E) want Qt bindings with Ruby scripts?
|
||||
parameters['no_qt_bindings'] = NoQtBindings
|
||||
|
|
@ -698,7 +727,7 @@ def Get_Build_Parameters(config):
|
|||
# <pymod> will be built if:
|
||||
# BuildPymod = True
|
||||
# Platform = [ 'Sonoma', 'Ventura', 'Monterey']
|
||||
# ModuleRuby = [ 'Ruby32MacPorts', 'Ruby32Brew', 'RubyAnaconda3' ]
|
||||
# ModuleRuby = [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]
|
||||
# ModulePython = [ 'Python311MacPorts', 'Python39MacPorts',
|
||||
# 'Python311Brew', Python39Brew', 'PythonAutoBrew',
|
||||
# 'PythonAnaconda3' ]
|
||||
|
|
@ -709,13 +738,13 @@ def Get_Build_Parameters(config):
|
|||
|
||||
PymodDistDir = dict()
|
||||
if Platform in [ 'Sonoma', 'Ventura', 'Monterey' ]:
|
||||
if ModuleRuby in [ 'Ruby32MacPorts', 'Ruby32Brew', 'RubyAnaconda3' ]:
|
||||
if ModuleRuby in [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]:
|
||||
if ModulePython in [ 'Python311MacPorts', 'Python39MacPorts' ]:
|
||||
PymodDistDir[ModulePython] = 'dist-MP3'
|
||||
PymodDistDir[ModulePython] = 'dist-MP3-%s' % ModuleQt
|
||||
elif ModulePython in [ 'Python311Brew', 'Python39Brew', 'PythonAutoBrew' ]:
|
||||
PymodDistDir[ModulePython] = 'dist-HB3'
|
||||
PymodDistDir[ModulePython] = 'dist-HB3-%s' % ModuleQt
|
||||
elif ModulePython in [ 'PythonAnaconda3' ]:
|
||||
PymodDistDir[ModulePython] = 'dist-ana3'
|
||||
PymodDistDir[ModulePython] = 'dist-ana3-%s' % ModuleQt
|
||||
parameters['pymod_dist'] = PymodDistDir
|
||||
return parameters
|
||||
|
||||
|
|
@ -732,7 +761,7 @@ def Build_pymod(parameters):
|
|||
# [1] <pymod> will be built if:
|
||||
# BuildPymod = True
|
||||
# Platform = [ 'Sonoma', 'Ventura', 'Monterey']
|
||||
# ModuleRuby = [ 'Ruby32MacPorts', 'Ruby32Brew', 'RubyAnaconda3' ]
|
||||
# ModuleRuby = [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]
|
||||
# ModulePython = [ 'Python311MacPorts', 'Python39MacPorts',
|
||||
# 'Python311Brew', Python39Brew', 'PythonAutoBrew',
|
||||
# 'PythonAnaconda3' ]
|
||||
|
|
@ -745,7 +774,7 @@ def Build_pymod(parameters):
|
|||
return 0
|
||||
if not Platform in [ 'Sonoma', 'Ventura', 'Monterey' ]:
|
||||
return 0
|
||||
elif not ModuleRuby in [ 'Ruby32MacPorts', 'Ruby32Brew', 'RubyAnaconda3' ]:
|
||||
elif not ModuleRuby in [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]:
|
||||
return 0
|
||||
elif not ModulePython in [ 'Python311MacPorts', 'Python39MacPorts', 'PythonAnaconda3', \
|
||||
'Python311Brew', 'Python39Brew', 'PythonAutoBrew' ]:
|
||||
|
|
@ -758,17 +787,17 @@ def Build_pymod(parameters):
|
|||
#--------------------------------------------------------------------
|
||||
PymodDistDir = parameters['pymod_dist']
|
||||
# Using MacPorts
|
||||
if PymodDistDir[ModulePython] == 'dist-MP3':
|
||||
if PymodDistDir[ModulePython].find('dist-MP3') >= 0:
|
||||
addBinPath = "/opt/local/bin"
|
||||
addIncPath = "/opt/local/include"
|
||||
addLibPath = "/opt/local/lib"
|
||||
# Using Homebrew
|
||||
elif PymodDistDir[ModulePython] == 'dist-HB3':
|
||||
elif PymodDistDir[ModulePython].find('dist-HB3') >= 0:
|
||||
addBinPath = "%s/bin" % DefaultHomebrewRoot # defined in "build4mac_env.py"
|
||||
addIncPath = "%s/include" % DefaultHomebrewRoot # -- ditto --
|
||||
addLibPath = "%s/lib" % DefaultHomebrewRoot # -- ditto --
|
||||
# Using Anaconda3
|
||||
elif PymodDistDir[ModulePython] == 'dist-ana3':
|
||||
elif PymodDistDir[ModulePython].find('dist-ana3') >= 0:
|
||||
addBinPath = "/Applications/anaconda3/bin"
|
||||
addIncPath = "/Applications/anaconda3/include"
|
||||
addLibPath = "/Applications/anaconda3/lib"
|
||||
|
|
@ -1149,7 +1178,7 @@ def Deploy_Binaries_For_Bundle(config, parameters):
|
|||
if BuildPymod:
|
||||
try:
|
||||
PymodDistDir = parameters['pymod_dist']
|
||||
pymodDistDir = PymodDistDir[ModulePython] # [ 'dist-MP3', 'dist-HB3', 'dist-ana3' ]
|
||||
pymodDistDir = PymodDistDir[ModulePython] # [ 'dist-MP3-${ModuleQt}', 'dist-HB3-${ModuleQt}', 'dist-ana3-${ModuleQt}' ]
|
||||
except KeyError:
|
||||
pymodDistDir = ""
|
||||
else:
|
||||
|
|
@ -1800,15 +1829,15 @@ def Deploy_Binaries_For_Bundle(config, parameters):
|
|||
return 1
|
||||
|
||||
#-------------------------------------------------------------
|
||||
# [10] Special deployment of Ruby3.2 from Homebrew?
|
||||
# [10] Special deployment of Ruby3.3 from Homebrew?
|
||||
#-------------------------------------------------------------
|
||||
deploymentRuby32HB = (ModuleRuby == 'Ruby32Brew')
|
||||
deploymentRuby32HB = (ModuleRuby == 'Ruby33Brew')
|
||||
if deploymentRuby32HB and NonOSStdLang:
|
||||
|
||||
print( "" )
|
||||
print( " [10] You have reached optional deployment of Ruby from %s ..." % HBRuby32Path )
|
||||
print( " [10] You have reached optional deployment of Ruby from %s ..." % HBRuby33Path )
|
||||
print( " [!!!] Sorry, the deployed package will not work properly since deployment of" )
|
||||
print( " Ruby3.2 from Homebrew is not yet supported." )
|
||||
print( " Ruby3.3 from Homebrew is not yet supported." )
|
||||
print( " Since you have Homebrew development environment, there two options:" )
|
||||
print( " (1) Retry to make a package with '-Y|--DEPLOY' option." )
|
||||
print( " This will not deploy any of Qt[5|6], Python, and Ruby from Homebrew." )
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#! /usr/bin/env python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#===============================================================================
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
#
|
||||
# Here are dictionaries of ...
|
||||
# different modules for building KLayout (http://www.klayout.de/index.php)
|
||||
# version 0.28.13 or later on different Apple Mac OSX platforms.
|
||||
# version 0.28.17 or later on different Apple Mac OSX platforms.
|
||||
#
|
||||
# This file is imported by 'build4mac.py' script.
|
||||
#===============================================================================
|
||||
|
|
@ -117,7 +117,7 @@ Qt6Brew = { 'qmake' : '%s/opt/qt@6/bin/qmake' % DefaultHomebrewRoot,
|
|||
#-----------------------------------------------------
|
||||
RubyNil = [ 'nil' ]
|
||||
RubySys = [ 'RubyMonterey', 'RubyVentura', 'RubySonoma' ]
|
||||
RubyExt = [ 'Ruby32MacPorts', 'Ruby32Brew', 'RubyAnaconda3' ]
|
||||
RubyExt = [ 'Ruby33MacPorts', 'Ruby33Brew', 'RubyAnaconda3' ]
|
||||
Rubies = RubyNil + RubySys + RubyExt
|
||||
|
||||
#-----------------------------------------------------
|
||||
|
|
@ -150,21 +150,21 @@ RubySonoma = { 'exe': '/System/Library/Frameworks/Ruby.framework/Versions/
|
|||
'lib': '%s/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/libruby.tbd' % SonomaSDK
|
||||
}
|
||||
|
||||
# Ruby 3.2 from MacPorts (https://www.macports.org/)
|
||||
# install with 'sudo port install ruby32'
|
||||
# [Key Type Name] = 'MP32'
|
||||
Ruby32MacPorts = { 'exe': '/opt/local/bin/ruby3.2',
|
||||
'inc': '/opt/local/include/ruby-3.2.2',
|
||||
'lib': '/opt/local/lib/libruby.3.2.dylib'
|
||||
# Ruby 3.3 from MacPorts (https://www.macports.org/)
|
||||
# install with 'sudo port install ruby33'
|
||||
# [Key Type Name] = 'MP33'
|
||||
Ruby33MacPorts = { 'exe': '/opt/local/bin/ruby3.3',
|
||||
'inc': '/opt/local/include/ruby-3.3.0',
|
||||
'lib': '/opt/local/lib/libruby.3.3.dylib'
|
||||
}
|
||||
|
||||
# Ruby 3.2 from Homebrew
|
||||
# install with 'brew install ruby@3.2'
|
||||
# [Key Type Name] = 'HB32'
|
||||
HBRuby32Path = '%s/opt/ruby@3.2' % DefaultHomebrewRoot
|
||||
Ruby32Brew = { 'exe': '%s/bin/ruby' % HBRuby32Path,
|
||||
'inc': '%s/include/ruby-3.2.0' % HBRuby32Path,
|
||||
'lib': '%s/lib/libruby.3.2.dylib' % HBRuby32Path
|
||||
# Ruby 3.3 from Homebrew
|
||||
# install with 'brew install ruby@3.3'
|
||||
# [Key Type Name] = 'HB33'
|
||||
HBRuby33Path = '%s/opt/ruby@3.3' % DefaultHomebrewRoot
|
||||
Ruby33Brew = { 'exe': '%s/bin/ruby' % HBRuby33Path,
|
||||
'inc': '%s/include/ruby-3.3.0' % HBRuby33Path,
|
||||
'lib': '%s/lib/libruby.3.3.dylib' % HBRuby33Path
|
||||
}
|
||||
|
||||
# Ruby 3.2 bundled with anaconda3 installed under /Applications/anaconda3/
|
||||
|
|
@ -181,8 +181,8 @@ RubyDictionary = { 'nil' : None,
|
|||
'RubyMonterey' : RubyMonterey,
|
||||
'RubyVentura' : RubyVentura,
|
||||
'RubySonoma' : RubySonoma,
|
||||
'Ruby32MacPorts': Ruby32MacPorts,
|
||||
'Ruby32Brew' : Ruby32Brew,
|
||||
'Ruby33MacPorts': Ruby33MacPorts,
|
||||
'Ruby33Brew' : Ruby33Brew,
|
||||
'RubyAnaconda3' : RubyAnaconda3
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +195,7 @@ RubyDictionary = { 'nil' : None,
|
|||
# for the previous states.
|
||||
#-----------------------------------------------------
|
||||
PythonNil = [ 'nil' ]
|
||||
PythonSys = [ ]
|
||||
PythonSys = [ 'PythonMonterey', 'PythonVentura', 'PythonSonoma' ]
|
||||
PythonExt = [ 'Python39MacPorts', 'Python39Brew' ]
|
||||
PythonExt += [ 'Python311MacPorts', 'Python311Brew' ]
|
||||
PythonExt += [ 'PythonAnaconda3', 'PythonAutoBrew' ]
|
||||
|
|
@ -204,6 +204,33 @@ Pythons = PythonNil + PythonSys + PythonExt
|
|||
#-----------------------------------------------------
|
||||
# Whereabouts of different components of Python
|
||||
#-----------------------------------------------------
|
||||
# Bundled with Monterey (12.x)
|
||||
# [Key Type Name] = 'Sys'
|
||||
MontereyPy3FWXc = "/Applications/Xcode.app/Contents/Developer/Library/Frameworks"
|
||||
MontereyPy3FW = "/Library/Developer/CommandLineTools/Library/Frameworks"
|
||||
PythonMonterey = { 'exe': '%s/Python3.framework/Versions/3.9/bin/python3.9' % MontereyPy3FW,
|
||||
'inc': '%s/Python3.framework/Versions/3.9/include/python3.9' % MontereyPy3FW,
|
||||
'lib': '%s/Python3.framework/Versions/3.9/lib/libpython3.9.dylib' % MontereyPy3FW
|
||||
}
|
||||
|
||||
# Bundled with Ventura (13.x)
|
||||
# [Key Type Name] = 'Sys'
|
||||
VenturaPy3FWXc = "/Applications/Xcode.app/Contents/Developer/Library/Frameworks"
|
||||
VenturaPy3FW = "/Library/Developer/CommandLineTools/Library/Frameworks"
|
||||
PythonVentura = { 'exe': '%s/Python3.framework/Versions/3.9/bin/python3.9' % VenturaPy3FW,
|
||||
'inc': '%s/Python3.framework/Versions/3.9/include/python3.9' % VenturaPy3FW,
|
||||
'lib': '%s/Python3.framework/Versions/3.9/lib/libpython3.9.dylib' % VenturaPy3FW
|
||||
}
|
||||
|
||||
# Bundled with Sonoma (14.x)
|
||||
# [Key Type Name] = 'Sys'
|
||||
SonomaPy3FWXc = "/Applications/Xcode.app/Contents/Developer/Library/Frameworks"
|
||||
SonomaPy3FW = "/Library/Developer/CommandLineTools/Library/Frameworks"
|
||||
PythonSonoma = { 'exe': '%s/Python3.framework/Versions/3.9/bin/python3.9' % SonomaPy3FW,
|
||||
'inc': '%s/Python3.framework/Versions/3.9/include/python3.9' % SonomaPy3FW,
|
||||
'lib': '%s/Python3.framework/Versions/3.9/lib/libpython3.9.dylib' % SonomaPy3FW
|
||||
}
|
||||
|
||||
# Python 3.9 from MacPorts (https://www.macports.org/)
|
||||
# install with 'sudo port install python39'
|
||||
# [Key Type Name] = 'MP39'
|
||||
|
|
@ -299,6 +326,9 @@ else:
|
|||
|
||||
# Consolidated dictionary kit for Python
|
||||
PythonDictionary = { 'nil' : None,
|
||||
'PythonMonterey' : PythonMonterey,
|
||||
'PythonVentura' : PythonVentura,
|
||||
'PythonSonoma' : PythonSonoma,
|
||||
'Python39MacPorts' : Python39MacPorts,
|
||||
'Python311MacPorts': Python311MacPorts,
|
||||
'Python39Brew' : Python39Brew,
|
||||
|
|
@ -312,7 +342,7 @@ if _have_Homebrew_Python:
|
|||
# [4] KLayout executables including buddy tools
|
||||
#-----------------------------------------------------
|
||||
KLayoutExecs = [ 'klayout' ]
|
||||
KLayoutExecs += [ 'strm2cif', 'strm2dxf', 'strm2gds', 'strm2gdstxt', 'strm2oas' ]
|
||||
KLayoutExecs += [ 'strm2cif', 'strm2dxf', 'strm2gds', 'strm2gdstxt', 'strm2mag', 'strm2oas' ]
|
||||
KLayoutExecs += [ 'strm2txt', 'strmclip', 'strmcmp', 'strmrun', 'strmxor' ]
|
||||
|
||||
#----------------
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#! /usr/bin/env python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#========================================================================================
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
#
|
||||
# Here are utility functions and classes ...
|
||||
# for building KLayout (http://www.klayout.de/index.php)
|
||||
# version 0.26.1 or later on different Apple Mac OSX platforms.
|
||||
# version 0.28.17 or later on different Apple Mac OSX platforms.
|
||||
#
|
||||
# This file is imported by 'build4mac.py' script.
|
||||
#========================================================================================
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
# File: "macbuild/macQAT.py"
|
||||
#
|
||||
# The top Python script to run "ut_runner" after building KLayout
|
||||
# (http://www.klayout.de/index.php) version 0.26.1 or later on different Apple
|
||||
# (http://www.klayout.de/index.php) version 0.28.17 or later on different Apple
|
||||
# ßMac OSX platforms.
|
||||
#
|
||||
# This script must be copied to a "*.macQAT/" directory to run.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
# File: "macbuild/macQAT.sh"
|
||||
#
|
||||
# The top Bash script to run "ut_runner" after building KLayout
|
||||
# (http://www.klayout.de/index.php) version 0.26.1 or later on different Apple
|
||||
# (http://www.klayout.de/index.php) version 0.25.17 or later on different Apple
|
||||
# Mac OSX platforms.
|
||||
#
|
||||
# This script must be copied to a "*.macQAT/" directory to run.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
# File: "macbuild/macQAT2.sh"
|
||||
#
|
||||
# The top Bash script to run "ut_runner" after building KLayout
|
||||
# (http://www.klayout.de/index.php) version 0.26.1 or later on different Apple
|
||||
# (http://www.klayout.de/index.php) version 0.28.17 or later on different Apple
|
||||
# Mac OSX platforms.
|
||||
#
|
||||
# This script must be copied to a directory that can be found in $PATH.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#! /usr/bin/env python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#=============================================================================================
|
||||
|
|
@ -63,7 +63,7 @@ def SetGlobals():
|
|||
global LatestOSHomebrew # True if 'LatestOS with Homebrew' and targeting LW-*
|
||||
global LatestOSAnaconda3 # True if 'LatestOS with Anaconda3' and targeting LW-*
|
||||
global LatestOSHomebrewH # True if 'LatestOS with Homebrew' and targeting HW-*
|
||||
global DicLightHeavyW # dictionary for LW-* and HW-* packages
|
||||
global DicStdLightHeavyW # dictionary for LW-* and HW-* packages
|
||||
global Item3AppleScript # ITEM_3 in the Apple script
|
||||
# auxiliary variables on platform
|
||||
global System # 6-tuple from platform.uname()
|
||||
|
|
@ -77,13 +77,13 @@ def SetGlobals():
|
|||
Usage = "\n"
|
||||
Usage += "---------------------------------------------------------------------------------------------------------\n"
|
||||
Usage += "<< Usage of 'makeDMG4mac.py' >>\n"
|
||||
Usage += " for making a DMG file of KLayout 0.28.13 or later on different Apple macOS platforms.\n"
|
||||
Usage += " for making a DMG file of KLayout 0.28.17 or later on different Apple macOS platforms.\n"
|
||||
Usage += "\n"
|
||||
Usage += "$ [python] ./makeDMG4mac.py\n"
|
||||
Usage += " option & argument : descriptions | default value\n"
|
||||
Usage += " ----------------------------------------------------------------------------------+-----------------\n"
|
||||
Usage += " <-p|--pkg <dir>> : package directory created by `build4mac.py` with [-y|-Y] | ``\n"
|
||||
Usage += " : like 'LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311' | \n"
|
||||
Usage += " : like 'LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311' | \n"
|
||||
Usage += " <-c|--clean> : clean the work directory | disabled\n"
|
||||
Usage += " <-m|--make> : make a compressed DMG file | disabled\n"
|
||||
Usage += " : <-c|--clean> and <-m|--make> are mutually exclusive | \n"
|
||||
|
|
@ -158,51 +158,59 @@ def SetGlobals():
|
|||
LatestOSHomebrew = False
|
||||
LatestOSAnaconda3 = False
|
||||
LatestOSHomebrewH = False
|
||||
DicLightHeavyW = dict()
|
||||
DicStdLightHeavyW = dict()
|
||||
Item3AppleScript = ""
|
||||
|
||||
# Populate DicLightHeavyW
|
||||
DicLightHeavyW[ "ports" ] = dict() # LW-*
|
||||
DicLightHeavyW[ "brew" ] = dict() # LW-*
|
||||
DicLightHeavyW[ "ana3" ] = dict() # LW-*
|
||||
DicLightHeavyW[ "brewH" ] = dict() # HW-*
|
||||
# Populate DicStdLightHeavyW
|
||||
DicStdLightHeavyW[ "std" ] = dict() # ST-*
|
||||
DicStdLightHeavyW[ "ports" ] = dict() # LW-*
|
||||
DicStdLightHeavyW[ "brew" ] = dict() # LW-*
|
||||
DicStdLightHeavyW[ "ana3" ] = dict() # LW-*
|
||||
DicStdLightHeavyW[ "brewH" ] = dict() # HW-*
|
||||
|
||||
DicLightHeavyW[ "ports" ]["zip"] = "macbuild/Resources/script-bundle-P.zip"
|
||||
DicLightHeavyW[ "ports" ]["src"] = "script-bundle-P"
|
||||
DicLightHeavyW[ "ports" ]["des"] = "MacPortsUser-ReadMeFirst"
|
||||
DicLightHeavyW[ "ports" ]["item3"] = 'set position of item "MacPortsUser-ReadMeFirst" to {700, 400}'
|
||||
DicStdLightHeavyW[ "std" ]["zip"] = "macbuild/Resources/script-bundle-S.zip"
|
||||
DicStdLightHeavyW[ "std" ]["src"] = "script-bundle-S"
|
||||
DicStdLightHeavyW[ "std" ]["des"] = "MacStdUser-ReadMeFirst"
|
||||
DicStdLightHeavyW[ "std" ]["item3"] = 'set position of item "MacStdUser-ReadMeFirst" to {700, 400}'
|
||||
|
||||
DicLightHeavyW[ "brew" ]["zip"] = "macbuild/Resources/script-bundle-B.zip"
|
||||
DicLightHeavyW[ "brew" ]["src"] = "script-bundle-B"
|
||||
DicLightHeavyW[ "brew" ]["des"] = "HomebrewUser-ReadMeFirst"
|
||||
DicLightHeavyW[ "brew" ]["item3"] = 'set position of item "HomebrewUser-ReadMeFirst" to {700, 400}'
|
||||
DicStdLightHeavyW[ "ports" ]["zip"] = "macbuild/Resources/script-bundle-P.zip"
|
||||
DicStdLightHeavyW[ "ports" ]["src"] = "script-bundle-P"
|
||||
DicStdLightHeavyW[ "ports" ]["des"] = "MacPortsUser-ReadMeFirst"
|
||||
DicStdLightHeavyW[ "ports" ]["item3"] = 'set position of item "MacPortsUser-ReadMeFirst" to {700, 400}'
|
||||
|
||||
DicLightHeavyW[ "ana3" ]["zip"] = "macbuild/Resources/script-bundle-A.zip"
|
||||
DicLightHeavyW[ "ana3" ]["src"] = "script-bundle-A"
|
||||
DicLightHeavyW[ "ana3" ]["des"] = "Anaconda3User-ReadMeFirst"
|
||||
DicLightHeavyW[ "ana3" ]["item3"] = 'set position of item "Anaconda3User-ReadMeFirst" to {700, 400}'
|
||||
DicStdLightHeavyW[ "brew" ]["zip"] = "macbuild/Resources/script-bundle-B.zip"
|
||||
DicStdLightHeavyW[ "brew" ]["src"] = "script-bundle-B"
|
||||
DicStdLightHeavyW[ "brew" ]["des"] = "HomebrewUser-ReadMeFirst"
|
||||
DicStdLightHeavyW[ "brew" ]["item3"] = 'set position of item "HomebrewUser-ReadMeFirst" to {700, 400}'
|
||||
|
||||
DicLightHeavyW[ "brewH" ]["zip"] = "macbuild/Resources/script-bundle-H.zip"
|
||||
DicLightHeavyW[ "brewH" ]["src"] = "script-bundle-H"
|
||||
DicLightHeavyW[ "brewH" ]["des"] = "Homebrew-HUser-ReadMeFirst"
|
||||
DicLightHeavyW[ "brewH" ]["item3"] = 'set position of item "Homebrew-HUser-ReadMeFirst" to {700, 400}'
|
||||
DicStdLightHeavyW[ "ana3" ]["zip"] = "macbuild/Resources/script-bundle-A.zip"
|
||||
DicStdLightHeavyW[ "ana3" ]["src"] = "script-bundle-A"
|
||||
DicStdLightHeavyW[ "ana3" ]["des"] = "Anaconda3User-ReadMeFirst"
|
||||
DicStdLightHeavyW[ "ana3" ]["item3"] = 'set position of item "Anaconda3User-ReadMeFirst" to {700, 400}'
|
||||
|
||||
DicStdLightHeavyW[ "brewH" ]["zip"] = "macbuild/Resources/script-bundle-H.zip"
|
||||
DicStdLightHeavyW[ "brewH" ]["src"] = "script-bundle-H"
|
||||
DicStdLightHeavyW[ "brewH" ]["des"] = "Homebrew-HUser-ReadMeFirst"
|
||||
DicStdLightHeavyW[ "brewH" ]["item3"] = 'set position of item "Homebrew-HUser-ReadMeFirst" to {700, 400}'
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
## To check the contents of the package directory
|
||||
#
|
||||
# The package directory name should look like:
|
||||
# * ST-qt5MP.pkg.macos-Monterey-release-RsysPsys
|
||||
# * LW-qt5Ana3.pkg.macos-Monterey-release-Rana3Pana3
|
||||
# * LW-qt5Brew.pkg.macos-Monterey-release-Rhb32Phb311 --- (1)
|
||||
# * LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311
|
||||
# * LW-qt5Brew.pkg.macos-Monterey-release-Rhb33Phb311 --- (1)
|
||||
# * LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311
|
||||
# * HW-qt5Brew.pkg.macos-Monterey-release-RsysPhb311
|
||||
#
|
||||
# * ST-qt6MP.pkg.macos-Monterey-release-RsysPsys
|
||||
# * LW-qt6Ana3.pkg.macos-Monterey-release-Rana3Pana3
|
||||
# * LW-qt6Brew.pkg.macos-Monterey-release-Rhb32Phb311
|
||||
# * LW-qt6MP.pkg.macos-Monterey-release-Rmp32Pmp311
|
||||
# * LW-qt6Brew.pkg.macos-Monterey-release-Rhb33Phb311
|
||||
# * LW-qt6MP.pkg.macos-Monterey-release-Rmp33Pmp311
|
||||
# * HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311
|
||||
#
|
||||
# Generated DMG will be, for example,
|
||||
# (1) ---> LW-klayout-0.28.13-macOS-Monterey-1-qt5Brew-Rhb32Phb311.dmg
|
||||
# (1) ---> LW-klayout-0.28.17-macOS-Monterey-1-qt5Brew-Rhb33Phb311.dmg
|
||||
#
|
||||
# @return on success, positive integer in [MB] that tells approx. occupied disc space;
|
||||
# on failure, -1
|
||||
|
|
@ -223,7 +231,7 @@ def CheckPkgDirectory():
|
|||
global LatestOSHomebrew
|
||||
global LatestOSAnaconda3
|
||||
global LatestOSHomebrewH
|
||||
global DicLightHeavyW
|
||||
global DicStdLightHeavyW
|
||||
global Item3AppleScript
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
|
@ -241,18 +249,20 @@ def CheckPkgDirectory():
|
|||
|
||||
#-----------------------------------------------------------------------------------------------
|
||||
# [2] Identify (Qt, Ruby, Python) from PkgDir
|
||||
# * ST-qt5MP.pkg.macos-Monterey-release-RsysPsys
|
||||
# * LW-qt5Ana3.pkg.macos-Monterey-release-Rana3Pana3
|
||||
# * LW-qt5Brew.pkg.macos-Monterey-release-Rhb32Phb311
|
||||
# * LW-qt5MP.pkg.macos-Monterey-release-Rmp32Pmp311
|
||||
# * LW-qt5Brew.pkg.macos-Monterey-release-Rhb33Phb311
|
||||
# * LW-qt5MP.pkg.macos-Monterey-release-Rmp33Pmp311
|
||||
# * HW-qt5Brew.pkg.macos-Monterey-release-RsysPhb311
|
||||
# * EX-qt5MP.pkg.macos-Monterey-release-Rhb32Pmp311
|
||||
# * EX-qt5MP.pkg.macos-Monterey-release-Rhb33Pmp311
|
||||
#
|
||||
# * ST-qt6MP.pkg.macos-Monterey-release-RsysPsys
|
||||
# * LW-qt6Ana3.pkg.macos-Monterey-release-Rana3Pana3
|
||||
# * LW-qt6Brew.pkg.macos-Monterey-release-Rhb32Phb311
|
||||
# * LW-qt6MP.pkg.macos-Monterey-release-Rmp32Pmp311
|
||||
# * LW-qt6Brew.pkg.macos-Monterey-release-Rhb33Phb311
|
||||
# * LW-qt6MP.pkg.macos-Monterey-release-Rmp33Pmp311
|
||||
# * HW-qt6Brew.pkg.macos-Monterey-release-RsysPhb311
|
||||
#-----------------------------------------------------------------------------------------------
|
||||
patQRP = u'(LW|HW|EX)([-])([qt5|qt6][0-9A-Za-z]+)([.]pkg[.])([A-Za-z]+[-][A-Za-z]+[-]release[-])([0-9A-Za-z]+)'
|
||||
patQRP = u'(ST|LW|HW|EX)([-])([qt5|qt6][0-9A-Za-z]+)([.]pkg[.])([A-Za-z]+[-][A-Za-z]+[-]release[-])([0-9A-Za-z]+)'
|
||||
regQRP = re.compile(patQRP)
|
||||
if not regQRP.match(PkgDir):
|
||||
print( "! Cannot identify (Qt, Ruby, Python) from the package directory name" )
|
||||
|
|
@ -277,15 +287,20 @@ def CheckPkgDirectory():
|
|||
#-----------------------------------------------------------------------------
|
||||
# [3] Check if the "LatestOS" with MacPorts / Homebrew / Anaconda3
|
||||
#-----------------------------------------------------------------------------
|
||||
LatestOSSys = Platform == LatestOS
|
||||
LatestOSSys &= PackagePrefix == "ST"
|
||||
LatestOSSys &= QtIdentification in [ "qt5MP", "qt6MP" ]
|
||||
LatestOSSys &= RubyPythonID in [ "RsysPsys" ]
|
||||
|
||||
LatestOSMacPorts = Platform == LatestOS
|
||||
LatestOSMacPorts &= PackagePrefix == "LW"
|
||||
LatestOSMacPorts &= QtIdentification in [ "qt5MP", "qt6MP" ]
|
||||
LatestOSMacPorts &= RubyPythonID in [ "Rmp32Pmp311", "Rmp32Pmp39" ]
|
||||
LatestOSMacPorts &= RubyPythonID in [ "Rmp33Pmp311", "Rmp33Pmp39" ]
|
||||
|
||||
LatestOSHomebrew = Platform == LatestOS
|
||||
LatestOSHomebrew &= PackagePrefix == "LW"
|
||||
LatestOSHomebrew &= QtIdentification in [ "qt5Brew", "qt6Brew" ]
|
||||
LatestOSHomebrew &= RubyPythonID in [ "Rhb32Phb311", "Rhb32Phb39", "Rhb32Phbauto" ]
|
||||
LatestOSHomebrew &= RubyPythonID in [ "Rhb33Phb311", "Rhb33Phb39", "Rhb33Phbauto" ]
|
||||
|
||||
LatestOSAnaconda3 = Platform == LatestOS
|
||||
LatestOSAnaconda3 &= PackagePrefix == "LW"
|
||||
|
|
@ -297,8 +312,23 @@ def CheckPkgDirectory():
|
|||
LatestOSHomebrewH &= QtIdentification in [ "qt5Brew", "qt6Brew" ]
|
||||
LatestOSHomebrewH &= RubyPythonID in [ "RsysPhb311", "RsysPhb39", "RsysPhbauto" ] # Sys-Homebre hybrid
|
||||
|
||||
if LatestOSSys:
|
||||
mydic = DicStdLightHeavyW["std"]
|
||||
srcDir = PkgDir + "/" + mydic["src"]
|
||||
desDir = PkgDir + "/" + mydic["des"]
|
||||
if OpMake:
|
||||
with zipfile.ZipFile( mydic["zip"], 'r' ) as zip_ref:
|
||||
zip_ref.extractall(PkgDir)
|
||||
os.rename( srcDir, desDir )
|
||||
if OpClean:
|
||||
if os.path.isdir(srcDir):
|
||||
shutil.rmtree(srcDir)
|
||||
if os.path.isdir(desDir):
|
||||
shutil.rmtree(desDir)
|
||||
Item3AppleScript = mydic["item3"]
|
||||
|
||||
if LatestOSMacPorts:
|
||||
mydic = DicLightHeavyW["ports"]
|
||||
mydic = DicStdLightHeavyW["ports"]
|
||||
srcDir = PkgDir + "/" + mydic["src"]
|
||||
desDir = PkgDir + "/" + mydic["des"]
|
||||
if OpMake:
|
||||
|
|
@ -313,7 +343,7 @@ def CheckPkgDirectory():
|
|||
Item3AppleScript = mydic["item3"]
|
||||
|
||||
if LatestOSHomebrew:
|
||||
mydic = DicLightHeavyW["brew"]
|
||||
mydic = DicStdLightHeavyW["brew"]
|
||||
srcDir = PkgDir + "/" + mydic["src"]
|
||||
desDir = PkgDir + "/" + mydic["des"]
|
||||
if OpMake:
|
||||
|
|
@ -328,7 +358,7 @@ def CheckPkgDirectory():
|
|||
Item3AppleScript = mydic["item3"]
|
||||
|
||||
if LatestOSAnaconda3:
|
||||
mydic = DicLightHeavyW["ana3"]
|
||||
mydic = DicStdLightHeavyW["ana3"]
|
||||
srcDir = PkgDir + "/" + mydic["src"]
|
||||
desDir = PkgDir + "/" + mydic["des"]
|
||||
if OpMake:
|
||||
|
|
@ -343,7 +373,7 @@ def CheckPkgDirectory():
|
|||
Item3AppleScript = mydic["item3"]
|
||||
|
||||
if LatestOSHomebrewH:
|
||||
mydic = DicLightHeavyW["brewH"]
|
||||
mydic = DicStdLightHeavyW["brewH"]
|
||||
srcDir = PkgDir + "/" + mydic["src"]
|
||||
desDir = PkgDir + "/" + mydic["des"]
|
||||
if OpMake:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#! /usr/bin/env python3
|
||||
#!/Applications/anaconda3/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
|
|
@ -8,6 +8,20 @@ import glob
|
|||
import platform
|
||||
import optparse
|
||||
import subprocess
|
||||
#------------------------------------------------------------------------------
|
||||
# In general, avoid setting the first line to '#!/usr/bin/env python3'.
|
||||
# If so, when this script is invoked in the 'KLayoutNightlyBuild.app' script
|
||||
# bundle created by Automator, the python3 will be the macOS-bundled python3,
|
||||
# where pandas is not included by default.
|
||||
# Therefore, it is better to use one of:
|
||||
# 1) #!/Applications/anaconda3/bin/python3 (Anaconda3)
|
||||
# 2) #!/usr/local/bin/python3 (Homebrew needs 'pip3 install pandas')
|
||||
# 3) #!/opt/local/bin/python3 (MacPorts needs 'sudo pip3 install pandas')
|
||||
#
|
||||
# However, if we install 'pandas' and its dependencies to the system Python
|
||||
# environment, we can also set '#!/usr/bin/env python3'.
|
||||
#------------------------------------------------------------------------------
|
||||
import pandas as pd
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
## To test if the platform is a member of valid platforms
|
||||
|
|
@ -44,7 +58,7 @@ def Test_My_Platform( platforms=[ 'Monterey', 'Ventura', 'Sonoma' ] ):
|
|||
#------------------------------------------------------------------------------
|
||||
def Get_Build_Target_Dict():
|
||||
buildTargetDic = dict()
|
||||
# buildTargetDic[0] = 'std'
|
||||
buildTargetDic[0] = 'std'
|
||||
buildTargetDic[1] = 'ports'
|
||||
buildTargetDic[2] = 'brew'
|
||||
buildTargetDic[3] = 'brewHW'
|
||||
|
|
@ -61,45 +75,47 @@ def Get_Build_Target_Dict():
|
|||
# @param[in] platform platform name
|
||||
#
|
||||
# @return (dictionary1, dictionary2)-tupple
|
||||
# dictionary1: key=mnemonic, value=build option list
|
||||
# dictionary2: key=mnemonic, value=log file name
|
||||
# dictionary1: key=(qtVer, mnemonic), value=build option list
|
||||
# dictionary2: key=(qtVer, mnemonic), value=log file name
|
||||
#------------------------------------------------------------------------------
|
||||
def Get_Build_Options( targetDic, platform ):
|
||||
if QtType == 5:
|
||||
qtType = "Qt5"
|
||||
else:
|
||||
qtType = "Qt6"
|
||||
|
||||
buildOp = dict()
|
||||
logfile = dict()
|
||||
for key in targetDic.keys():
|
||||
target = targetDic[key]
|
||||
if target == "std": # use 'Qt5MacPorts' that provides Qt 5.15.2~ to run on "Big Sur", too
|
||||
buildOp["std"] = [ '-q', '%sMacPorts' % qtType, '-r', 'sys', '-p', 'sys' ]
|
||||
logfile["std"] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPsys")
|
||||
elif target == "ports":
|
||||
buildOp["ports"] = [ '-q', '%sMacPorts' % qtType, '-r', 'MP32', '-p', 'MP311' ]
|
||||
logfile["ports"] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rmp32Pmp311")
|
||||
elif target == "brew":
|
||||
buildOp["brew"] = [ '-q', '%sBrew' % qtType, '-r', 'HB32', '-p', 'HB311' ]
|
||||
logfile["brew"] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb32Phb311")
|
||||
elif target == "brewHW":
|
||||
buildOp["brewHW"] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HB311' ]
|
||||
logfile["brewHW"] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhb311")
|
||||
elif target == "ana3":
|
||||
buildOp["ana3"] = [ '-q', '%sAna3' % qtType, '-r', 'Ana3', '-p', 'Ana3' ]
|
||||
logfile["ana3"] = "%sAna3.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rana3Pana3")
|
||||
elif target == "brewA":
|
||||
buildOp["brewA"] = [ '-q', '%sBrew' % qtType, '-r', 'HB32', '-p', 'HBAuto' ]
|
||||
logfile["brewA"] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb32Phbauto")
|
||||
elif target == "brewAHW":
|
||||
buildOp["brewAHW"] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HBAuto' ]
|
||||
logfile["brewAHW"] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhbauto")
|
||||
|
||||
if WithPymod:
|
||||
buildOp["ports"] = buildOp["ports"] + ['--buildPymod']
|
||||
buildOp["brew"] = buildOp["brew"] + ['--buildPymod']
|
||||
buildOp["ana3"] = buildOp["ana3"] + ['--buildPymod']
|
||||
for qtVer in [5, 6]:
|
||||
if qtVer == 5:
|
||||
qtType = "Qt5"
|
||||
elif qtVer == 6:
|
||||
qtType = "Qt6"
|
||||
|
||||
for key in targetDic.keys():
|
||||
target = targetDic[key]
|
||||
if target == "std":
|
||||
buildOp[(qtVer, "std")] = [ '-q', '%sMacPorts' % qtType, '-r', 'sys', '-p', 'sys' ]
|
||||
logfile[(qtVer, "std")] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPsys")
|
||||
elif target == "ports":
|
||||
buildOp[(qtVer, "ports")] = [ '-q', '%sMacPorts' % qtType, '-r', 'MP33', '-p', 'MP311' ]
|
||||
logfile[(qtVer, "ports")] = "%sMP.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rmp33Pmp311")
|
||||
elif target == "brew":
|
||||
buildOp[(qtVer, "brew")] = [ '-q', '%sBrew' % qtType, '-r', 'HB33', '-p', 'HB311' ]
|
||||
logfile[(qtVer, "brew")] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb33Phb311")
|
||||
elif target == "brewHW":
|
||||
buildOp[(qtVer, "brewHW")] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HB311' ]
|
||||
logfile[(qtVer, "brewHW")] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhb311")
|
||||
elif target == "ana3":
|
||||
buildOp[(qtVer, "ana3")] = [ '-q', '%sAna3' % qtType, '-r', 'Ana3', '-p', 'Ana3' ]
|
||||
logfile[(qtVer, "ana3")] = "%sAna3.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rana3Pana3")
|
||||
elif target == "brewA":
|
||||
buildOp[(qtVer, "brewA")] = [ '-q', '%sBrew' % qtType, '-r', 'HB33', '-p', 'HBAuto' ]
|
||||
logfile[(qtVer, "brewA")] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "Rhb33Phbauto")
|
||||
elif target == "brewAHW":
|
||||
buildOp[(qtVer, "brewAHW")] = [ '-q', '%sBrew' % qtType, '-r', 'sys', '-p', 'HBAuto' ]
|
||||
logfile[(qtVer, "brewAHW")] = "%sBrew.build.macos-%s-%s-%s.log" % (qtType.lower(), platform, "release", "RsysPhbauto")
|
||||
|
||||
if WithPymod:
|
||||
buildOp[(qtVer,"ports")] = buildOp[(qtVer,"ports")] + ['--buildPymod']
|
||||
buildOp[(qtVer,"brew")] = buildOp[(qtVer,"brew")] + ['--buildPymod']
|
||||
buildOp[(qtVer,"ana3")] = buildOp[(qtVer,"ana3")] + ['--buildPymod']
|
||||
|
||||
return (buildOp, logfile)
|
||||
|
||||
|
|
@ -109,29 +125,34 @@ def Get_Build_Options( targetDic, platform ):
|
|||
# @param[in] targetDic build target dictionary
|
||||
# @param[in] platform platform name
|
||||
#
|
||||
# @return a dictionary; key=mnemonic, value=".macQAT" directory
|
||||
# @return a dictionary; key=(qtVer, mnemonic), value=".macQAT" directory
|
||||
#------------------------------------------------------------------------------
|
||||
def Get_QAT_Directory( targetDic, platform ):
|
||||
if QtType == 5:
|
||||
qtType = "qt5"
|
||||
else:
|
||||
qtType = "qt6"
|
||||
|
||||
dirQAT = dict()
|
||||
for key in targetDic.keys():
|
||||
target = targetDic[key]
|
||||
if target == "ports":
|
||||
dirQAT["ports"] = '%sMP.build.macos-%s-release-Rmp32Pmp311.macQAT' % (qtType, platform)
|
||||
elif target == "brew":
|
||||
dirQAT["brew"] = '%sBrew.build.macos-%s-release-Rhb32Phb311.macQAT' % (qtType, platform)
|
||||
elif target == "brewHW":
|
||||
dirQAT["brewHW"] = '%sBrew.build.macos-%s-release-RsysPhb311.macQAT' % (qtType, platform)
|
||||
elif target == "ana3":
|
||||
dirQAT["ana3"] = '%sAna3.build.macos-%s-release-Rana3Pana3.macQAT' % (qtType, platform)
|
||||
elif target == "brewA":
|
||||
dirQAT["brewA"] = '%sBrew.build.macos-%s-release-Rhb32Phbauto.macQAT' % (qtType, platform)
|
||||
elif target == "brewAHW":
|
||||
dirQAT["brewAHW"] = '%sBrew.build.macos-%s-release-RsysPhbauto.macQAT' % (qtType, platform)
|
||||
|
||||
for qtVer in [5, 6]:
|
||||
if qtVer == 5:
|
||||
qtType = "Qt5"
|
||||
elif qtVer == 6:
|
||||
qtType = "Qt6"
|
||||
|
||||
for key in targetDic.keys():
|
||||
target = targetDic[key]
|
||||
if target == "std":
|
||||
dirQAT[(qtVer, "std")] = '%sMP.build.macos-%s-release-RsysPsys.macQAT' % (qtType.lower(), platform)
|
||||
elif target == "ports":
|
||||
dirQAT[(qtVer, "ports")] = '%sMP.build.macos-%s-release-Rmp33Pmp311.macQAT' % (qtType.lower(), platform)
|
||||
elif target == "brew":
|
||||
dirQAT[(qtVer, "brew")] = '%sBrew.build.macos-%s-release-Rhb33Phb311.macQAT' % (qtType.lower(), platform)
|
||||
elif target == "brewHW":
|
||||
dirQAT[(qtVer, "brewHW")] = '%sBrew.build.macos-%s-release-RsysPhb311.macQAT' % (qtType.lower(), platform)
|
||||
elif target == "ana3":
|
||||
dirQAT[(qtVer, "ana3")] = '%sAna3.build.macos-%s-release-Rana3Pana3.macQAT' % (qtType.lower(), platform)
|
||||
elif target == "brewA":
|
||||
dirQAT[(qtVer, "brewA")] = '%sBrew.build.macos-%s-release-Rhb33Phbauto.macQAT' % (qtType.lower(), platform)
|
||||
elif target == "brewAHW":
|
||||
dirQAT[(qtVer, "brewAHW")] = '%sBrew.build.macos-%s-release-RsysPhbauto.macQAT' % (qtType.lower(), platform)
|
||||
|
||||
return dirQAT
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
|
@ -142,40 +163,45 @@ def Get_QAT_Directory( targetDic, platform ):
|
|||
# @param[in] srlDMG serial number of DMG
|
||||
# @param[in] makeflag True to make; False to clean
|
||||
#
|
||||
# @return a dictionary; key=mnemonic, value=build option list
|
||||
# @return a dictionary; key=(qtVer, mnemonic), value=build option list
|
||||
#------------------------------------------------------------------------------
|
||||
def Get_Package_Options( targetDic, platform, srlDMG, makeflag ):
|
||||
if QtType == 5:
|
||||
qtType = "qt5"
|
||||
else:
|
||||
qtType = "qt6"
|
||||
packOp = dict()
|
||||
|
||||
if makeflag:
|
||||
flag = '-m'
|
||||
else:
|
||||
flag = '-c'
|
||||
|
||||
packOp = dict()
|
||||
for key in targetDic.keys():
|
||||
target = targetDic[key]
|
||||
if target == "ports":
|
||||
packOp["ports"] = [ '-p', 'LW-%sMP.pkg.macos-%s-release-Rmp32Pmp311' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brew":
|
||||
packOp["brew"] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb32Phb311' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brewHW":
|
||||
packOp["brewHW"] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhb311' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "ana3":
|
||||
packOp["ana3"] = [ '-p', 'LW-%sAna3.pkg.macos-%s-release-Rana3Pana3' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brewA":
|
||||
packOp["brewA"] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb32Phbauto' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brewAHW":
|
||||
packOp["brewAHW"] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhbauto' % (qtType, platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
for qtVer in [5, 6]:
|
||||
if qtVer == 5:
|
||||
qtType = "Qt5"
|
||||
elif qtVer == 6:
|
||||
qtType = "Qt6"
|
||||
|
||||
for key in targetDic.keys():
|
||||
target = targetDic[key]
|
||||
if target == "std":
|
||||
packOp[(qtVer, "std")] = [ '-p', 'ST-%sMP.pkg.macos-%s-release-RsysPsys' % (qtType.lower(), platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "ports":
|
||||
packOp[(qtVer, "ports")] = [ '-p', 'LW-%sMP.pkg.macos-%s-release-Rmp33Pmp311' % (qtType.lower(), platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brew":
|
||||
packOp[(qtVer, "brew")] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb33Phb311' % (qtType.lower(), platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brewHW":
|
||||
packOp[(qtVer, "brewHW")] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhb311' % (qtType.lower(), platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "ana3":
|
||||
packOp[(qtVer, "ana3")] = [ '-p', 'LW-%sAna3.pkg.macos-%s-release-Rana3Pana3' % (qtType.lower(), platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brewA":
|
||||
packOp[(qtVer, "brewA")] = [ '-p', 'LW-%sBrew.pkg.macos-%s-release-Rhb33Phbauto' % (qtType.lower(), platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
elif target == "brewAHW":
|
||||
packOp[(qtVer, "brewAHW")] = [ '-p', 'HW-%sBrew.pkg.macos-%s-release-RsysPhbauto' % (qtType.lower(), platform),
|
||||
'-s', '%d' % srlDMG, '%s' % flag ]
|
||||
return packOp
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
|
@ -185,6 +211,7 @@ def Parse_CommandLine_Arguments():
|
|||
global Usage # usage
|
||||
global QtType # Qt type
|
||||
global Target # target list
|
||||
global QtTarget # list of (Qt, target)-tuple
|
||||
global Build # operation flag
|
||||
global WithPymod # operation flag
|
||||
global QATest # operation flag
|
||||
|
|
@ -198,9 +225,9 @@ def Parse_CommandLine_Arguments():
|
|||
|
||||
platform = Test_My_Platform()
|
||||
if platform in [ "Sonoma", "Ventura", "Monterey" ]:
|
||||
targetopt = "1,2,3,4"
|
||||
targetopt = "0,1,2,3,4"
|
||||
else:
|
||||
targetopt = "0"
|
||||
targetopt = None
|
||||
|
||||
Usage = "\n"
|
||||
Usage += "----------------------------------------------------------------------------------------------------------\n"
|
||||
|
|
@ -209,33 +236,39 @@ def Parse_CommandLine_Arguments():
|
|||
Usage += " macOS Monterey, Ventura, or Sonoma >>\n"
|
||||
Usage += "\n"
|
||||
Usage += "$ [python] nightlyBuild.py\n"
|
||||
Usage += " option & argument : comment on option if any | default value\n"
|
||||
Usage += " ------------------------------------------------------------------------+--------------\n"
|
||||
Usage += " [--qt <type>] : 5='qt5', 6='qt6' (migration to Qt6 is ongoing) | 5\n"
|
||||
Usage += " [--target <list>] : 1='ports', 2='brew', 3='brewHW', 4='ana3', | '%s'\n" % targetopt
|
||||
Usage += " 5='brewA', 6='brewAHW' |\n"
|
||||
Usage += " * with --qt=6, use --target='2,3' (4 is ignored) |\n"
|
||||
Usage += " [--build] : build and deploy | disabled\n"
|
||||
Usage += " [--pymod] : build and deploy Pymod, too | disabled\n"
|
||||
Usage += " [--test] : run the QA Test | disabled\n"
|
||||
Usage += " [--check] : check the QA Test results | disabled\n"
|
||||
Usage += " [--makedmg|--cleandmg <srlno>] : make or clean DMGs | disabled\n"
|
||||
Usage += " [--upload <dropbox>] : upload DMGs to $HOME/Dropbox/klayout/<dropbox> | disabled\n"
|
||||
Usage += " [--dryrun] : dry-run for --build option | disabled\n"
|
||||
Usage += " [-?|--?] : print this usage and exit | disabled\n"
|
||||
Usage += " |\n"
|
||||
Usage += " To use this script, make a symbolic link in the project root by: |\n"
|
||||
Usage += " $ ln -s ./macbuild/nightlyBuild.py . |\n"
|
||||
Usage += " |\n"
|
||||
Usage += " Regular sequence for using this script: |\n"
|
||||
Usage += " (1) $ ./nightlyBuild.py --build --pymod |\n"
|
||||
Usage += " (2) (confirm the build results) |\n"
|
||||
Usage += " (3) $ ./nightlyBuild.py --test |\n"
|
||||
Usage += " (4) $ ./nightlyBuild.py --check (confirm the QA Test results) |\n"
|
||||
Usage += " (5) $ ./nightlyBuild.py --makedmg 1 |\n"
|
||||
Usage += " (6) $ ./nightlyBuild.py --upload '0.28.12' |\n"
|
||||
Usage += " (7) $ ./nightlyBuild.py --cleandmg 1 |\n"
|
||||
Usage += "---------------------------------------------------------------------------+------------------------------\n"
|
||||
Usage += " option & argument : comment on option if any | default value\n"
|
||||
Usage += " --------------------------------------------------------------------------+--------------\n"
|
||||
Usage += " [--qt <type>] : 5='qt5', 6='qt6' (migration to Qt6 is ongoing) | 5\n"
|
||||
Usage += " [--target <list>] : 0='std', 1='ports', 2='brew', 3='brewHW', 4='ana3', | '%s'\n" % targetopt
|
||||
Usage += " 5='brewA', 6='brewAHW' |\n"
|
||||
Usage += " * with --qt=6, use --target='0,1,2,3' (4 is ignored) |\n"
|
||||
Usage += " [--qttarget <tuple list>] : ex. '5,1' for qt=5, target=1 | disabled\n"
|
||||
Usage += " + This option supersedes, if used, the --qt and --target combination. |\n"
|
||||
Usage += " + You can use this option multiple times. |\n"
|
||||
Usage += " + Or you can pass those list by the 'nightlyBuild.csv' file. |\n"
|
||||
Usage += " A sample file 'macbuild/nightlyBuild.sample.csv' is available. |\n"
|
||||
Usage += " [--build] : build and deploy | disabled\n"
|
||||
Usage += " [--pymod] : build and deploy Pymod, too | disabled\n"
|
||||
Usage += " [--test] : run the QA Test | disabled\n"
|
||||
Usage += " [--check] : check the QA Test results | disabled\n"
|
||||
Usage += " [--makedmg|--cleandmg <srlno>] : make or clean DMGs | disabled\n"
|
||||
Usage += " [--upload <dropbox>] : upload DMGs to $HOME/Dropbox/klayout/<dropbox> | disabled\n"
|
||||
Usage += " [--dryrun] : dry-run for --build option | disabled\n"
|
||||
Usage += " [-?|--?] : print this usage and exit | disabled\n"
|
||||
Usage += " |\n"
|
||||
Usage += " To use this script, make a symbolic link in the project root by: |\n"
|
||||
Usage += " $ ln -s ./macbuild/nightlyBuild.py . |\n"
|
||||
Usage += " + edit and save ./macbuild/nightlyBuild.csv (optional) |\n"
|
||||
Usage += " |\n"
|
||||
Usage += " Regular sequence for using this script: |\n"
|
||||
Usage += " (1) $ ./nightlyBuild.py --build --pymod |\n"
|
||||
Usage += " (2) (confirm the build results) |\n"
|
||||
Usage += " (3) $ ./nightlyBuild.py --test |\n"
|
||||
Usage += " (4) $ ./nightlyBuild.py --check (confirm the QA Test results) |\n"
|
||||
Usage += " (5) $ ./nightlyBuild.py --makedmg 1 |\n"
|
||||
Usage += " (6) $ ./nightlyBuild.py --upload '0.28.17' |\n"
|
||||
Usage += " (7) $ ./nightlyBuild.py --cleandmg 1 |\n"
|
||||
Usage += "-----------------------------------------------------------------------------+----------------------------\n"
|
||||
|
||||
p = optparse.OptionParser( usage=Usage )
|
||||
p.add_option( '--qt',
|
||||
|
|
@ -246,6 +279,11 @@ def Parse_CommandLine_Arguments():
|
|||
dest='targets',
|
||||
help='build target list' )
|
||||
|
||||
p.add_option( '--qttarget',
|
||||
action='append',
|
||||
dest='qt_target',
|
||||
help='(Qt, target)-tuple' )
|
||||
|
||||
p.add_option( '--build',
|
||||
action='store_true',
|
||||
dest='build',
|
||||
|
|
@ -296,6 +334,7 @@ def Parse_CommandLine_Arguments():
|
|||
|
||||
p.set_defaults( qt_type = "5",
|
||||
targets = "%s" % targetopt,
|
||||
qt_target = list(),
|
||||
build = False,
|
||||
with_pymod = False,
|
||||
qa_test = False,
|
||||
|
|
@ -331,9 +370,51 @@ def Parse_CommandLine_Arguments():
|
|||
targetDic = Get_Build_Target_Dict()
|
||||
Target = list()
|
||||
for idx in targetIdx:
|
||||
if idx in range(1, 7):
|
||||
if idx in range(0, 7):
|
||||
Target.append( targetDic[idx] )
|
||||
|
||||
# Populate QtTarget
|
||||
QtTarget = list()
|
||||
for target in Target:
|
||||
QtTarget.append( (QtType, target) )
|
||||
QtType = None
|
||||
Target = None
|
||||
print( "# The --qt and --target combination specifies..." )
|
||||
print(QtTarget)
|
||||
|
||||
if len(opt.qt_target) == 1 and opt.qt_target[0] == "nightlyBuild.csv": # reserved file name
|
||||
QtTarget = list()
|
||||
withqttarget = True
|
||||
df = pd.read_csv( opt.qt_target[0], comment="#" )
|
||||
if len(df) == 0:
|
||||
print( "! --qttarget==nightlyBuild.csv is used but DataFrame is empty" )
|
||||
print(Usage)
|
||||
quit()
|
||||
for i in range(0, len(df)):
|
||||
qt = df.iloc[i,0]
|
||||
idx = df.iloc[i,1]
|
||||
if (qt == 5 and idx in range(0, 7)) or (qt == 6 and idx in [0,1,2,3, 5,6]):
|
||||
QtTarget.append( (qt, targetDic[idx]) )
|
||||
elif len(opt.qt_target) > 0:
|
||||
QtTarget = list()
|
||||
withqttarget = True
|
||||
for item in opt.qt_target:
|
||||
qt = int(item.split(",")[0])
|
||||
idx = int(item.split(",")[1])
|
||||
if (qt == 5 and idx in range(0, 7)) or (qt == 6 and idx in [0,1,2,3, 5,6]):
|
||||
QtTarget.append( (qt, targetDic[idx]) )
|
||||
else:
|
||||
withqttarget = False
|
||||
|
||||
if withqttarget:
|
||||
if len(QtTarget) > 0:
|
||||
print( "# The --qttarget option superseded the --qt and --target combination" )
|
||||
print(QtTarget)
|
||||
else:
|
||||
print( "! --qttarget is used but there is no valid (Qt, target)-tuple" )
|
||||
print(Usage)
|
||||
quit()
|
||||
|
||||
Build = opt.build
|
||||
WithPymod = opt.with_pymod
|
||||
QATest = opt.qa_test
|
||||
|
|
@ -373,17 +454,18 @@ def Build_Deploy():
|
|||
myPlatform = Test_My_Platform()
|
||||
buildOp, logfile = Get_Build_Options( Get_Build_Target_Dict(), myPlatform )
|
||||
|
||||
for key in Target:
|
||||
if key == "ana3" and QtType == 6: # anaconda3 does not provide Qt6 so far
|
||||
for qttype, key in QtTarget:
|
||||
if key == "ana3" and qttype == 6: # anaconda3 does not provide Qt6 so far
|
||||
continue
|
||||
deplog = logfile[key].replace( ".log", ".dep.log" )
|
||||
|
||||
command1 = [ pyBuilder ] + buildOp[key]
|
||||
deplog = logfile[(qttype, key)].replace( ".log", ".dep.log" )
|
||||
|
||||
if key in [ "brewHW", "brewAHW" ] :
|
||||
command1 = [ pyBuilder ] + buildOp[(qttype, key)]
|
||||
|
||||
if key in [ "std", "brewHW", "brewAHW" ] :
|
||||
command2 = "time"
|
||||
command2 += " \\\n %s" % pyBuilder
|
||||
for option in buildOp[key]:
|
||||
for option in buildOp[(qttype, key)]:
|
||||
command2 += " \\\n %s" % option
|
||||
command2 += " \\\n %s" % '-y'
|
||||
command2 += " 2>&1 | tee %s; \\\n" % deplog
|
||||
|
|
@ -391,7 +473,7 @@ def Build_Deploy():
|
|||
else:
|
||||
command2 = "time"
|
||||
command2 += " \\\n %s" % pyBuilder
|
||||
for option in buildOp[key]:
|
||||
for option in buildOp[(qttype, key)]:
|
||||
command2 += " \\\n %s" % option
|
||||
command2 += " \\\n %s" % '-Y'
|
||||
command2 += " 2>&1 | tee %s; \\\n" % deplog
|
||||
|
|
@ -442,14 +524,14 @@ def Run_QATest( exclude ):
|
|||
myPlatform = Test_My_Platform()
|
||||
dirQAT = Get_QAT_Directory( Get_Build_Target_Dict(), myPlatform )
|
||||
|
||||
for key in Target:
|
||||
if key == 4 and QtType == 6: # anaconda3 does not provide Qt6 so far
|
||||
for qttype, key in QtTarget:
|
||||
if key == "ana3" and qttype == 6: # anaconda3 does not provide Qt6 so far
|
||||
continue
|
||||
|
||||
command1 = [ pyRunnerQAT ] + [ '--run', '--exclude', '%s' % exclude ]
|
||||
print( dirQAT[key], command1 )
|
||||
print( dirQAT[(qttype, key)], command1 )
|
||||
#continue
|
||||
os.chdir( dirQAT[key] )
|
||||
os.chdir( dirQAT[(qttype, key)] )
|
||||
|
||||
if subprocess.call( command1, shell=False ) != 0:
|
||||
print( "", file=sys.stderr )
|
||||
|
|
@ -477,14 +559,14 @@ def Check_QATest_Results( lines ):
|
|||
myPlatform = Test_My_Platform()
|
||||
dirQAT = Get_QAT_Directory( Get_Build_Target_Dict(), myPlatform )
|
||||
|
||||
for key in Target:
|
||||
if key == 4 and QtType == 6: # anaconda3 does not provide Qt6 so far
|
||||
for qttype, key in QtTarget:
|
||||
if key == "ana3" and qttype == 6: # anaconda3 does not provide Qt6 so far
|
||||
continue
|
||||
|
||||
os.chdir( dirQAT[key] )
|
||||
os.chdir( dirQAT[(qttype, key)] )
|
||||
logfile = glob.glob( "*.log" )
|
||||
command1 = [ tailCommand ] + [ '-n', '%d' % lines ] + logfile
|
||||
print( dirQAT[key], command1 )
|
||||
print( dirQAT[(qttype, key)], command1 )
|
||||
#continue
|
||||
|
||||
if subprocess.call( command1, shell=False ) != 0:
|
||||
|
|
@ -518,11 +600,11 @@ def DMG_Make( srlDMG ):
|
|||
shutil.rmtree( stashDMG )
|
||||
os.mkdir( stashDMG )
|
||||
|
||||
for key in Target:
|
||||
if key == 4 and QtType == 6: # anaconda3 does not provide Qt6 so far
|
||||
for qttype, key in QtTarget:
|
||||
if key == "ana3" and qttype == 6: # anaconda3 does not provide Qt6 so far
|
||||
continue
|
||||
|
||||
command1 = [ pyDMGmaker ] + packOp[key]
|
||||
command1 = [ pyDMGmaker ] + packOp[(qttype, key)]
|
||||
print(command1)
|
||||
#continue
|
||||
|
||||
|
|
@ -558,11 +640,11 @@ def DMG_Clean( srlDMG ):
|
|||
if os.path.isdir( stashDMG ):
|
||||
shutil.rmtree( stashDMG )
|
||||
|
||||
for key in Target:
|
||||
if key == 4 and QtType == 6: # anaconda3 does not provide Qt6 so far
|
||||
for qttype, key in QtTarget:
|
||||
if key == "ana3" and qttype == 6: # anaconda3 does not provide Qt6 so far
|
||||
continue
|
||||
|
||||
command1 = [ pyDMGmaker ] + packOp[key]
|
||||
command1 = [ pyDMGmaker ] + packOp[(qttype, key)]
|
||||
print(command1)
|
||||
#continue
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
#-------------------------------------------------------------------------------
|
||||
# File: 'nightlyBuild.csv'
|
||||
#
|
||||
# Descriptions:
|
||||
# This file (located where "build.sh" exists) is to be passed to
|
||||
# 'nightlyBuild.py' via the --qttarget option.
|
||||
#
|
||||
# qtVer,target
|
||||
# where
|
||||
# qtVer = 5 or 6
|
||||
# target = [0='std', 1='ports', 2='brew', 3='brewHW', 4='ana3']
|
||||
# note that
|
||||
# (qtVer,target)=(6,4) will be omitted
|
||||
#-------------------------------------------------------------------------------
|
||||
qtVer,target
|
||||
5,0
|
||||
5,1
|
||||
5,2
|
||||
5,3
|
||||
5,4
|
||||
#6,0
|
||||
#6,1
|
||||
#6,2
|
||||
#6,3
|
||||
#6,4
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 30.
|
|
|
@ -1,4 +1,4 @@
|
|||
#! /usr/bin/env python3
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#==============================================================================
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>668</width>
|
||||
<height>410</height>
|
||||
<width>745</width>
|
||||
<height>438</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
|
@ -845,7 +845,12 @@
|
|||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Angle measurement (three mouse clicks)</string>
|
||||
<string>Auto measure along edge (points will be set automatically)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Angle or radius measurement (three mouse clicks)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
|||
|
|
@ -247,6 +247,8 @@ RulerModeConverter::to_string (ant::Template::ruler_mode_type m)
|
|||
return "single_click";
|
||||
} else if (m == ant::Template::RulerAutoMetric) {
|
||||
return "auto_metric";
|
||||
} else if (m == ant::Template::RulerAutoMetricEdge) {
|
||||
return "auto_metric_edge";
|
||||
} else if (m == ant::Template::RulerMultiSegment) {
|
||||
return "multi_segment";
|
||||
} else if (m == ant::Template::RulerThreeClicks) {
|
||||
|
|
@ -266,6 +268,8 @@ RulerModeConverter::from_string (const std::string &s, ant::Template::ruler_mode
|
|||
a = ant::Template::RulerSingleClick;
|
||||
} else if (t == "auto_metric") {
|
||||
a = ant::Template::RulerAutoMetric;
|
||||
} else if (t == "auto_metric_edge") {
|
||||
a = ant::Template::RulerAutoMetricEdge;
|
||||
} else if (t == "multi_segment") {
|
||||
a = ant::Template::RulerMultiSegment;
|
||||
} else if (t == "angle") {
|
||||
|
|
|
|||
|
|
@ -60,6 +60,9 @@ static std::vector<ant::Template> make_standard_templates ()
|
|||
templates.push_back (ant::Template (tl::to_string (tr ("Measure")), "$X", "$Y", "$D", ant::Object::STY_ruler, ant::Object::OL_diag, true, lay::AC_Global, "_measure"));
|
||||
templates.back ().set_mode (ant::Template::RulerAutoMetric);
|
||||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Measure edge")), "$X", "$Y", "$D", ant::Object::STY_ruler, ant::Object::OL_diag, true, lay::AC_Global, "_measure_edge"));
|
||||
templates.back ().set_mode (ant::Template::RulerAutoMetricEdge);
|
||||
|
||||
templates.push_back (ant::Template (tl::to_string (tr ("Angle")), "", "", "$(sprintf('%.5g',G))°", ant::Object::STY_line, ant::Object::OL_angle, true, lay::AC_Global, "_angle"));
|
||||
templates.back ().set_mode (ant::Template::RulerThreeClicks);
|
||||
|
||||
|
|
|
|||
|
|
@ -1056,8 +1056,18 @@ Service::Service (db::Manager *manager, lay::LayoutViewBase *view)
|
|||
m_drawing (false), m_current (),
|
||||
m_move_mode (MoveNone),
|
||||
m_seg_index (0),
|
||||
m_current_template (0)
|
||||
{
|
||||
m_current_template (0),
|
||||
m_hover (false),
|
||||
m_hover_wait (false),
|
||||
m_hover_buttons (0),
|
||||
m_mouse_in_window (false)
|
||||
{
|
||||
#if defined(HAVE_QT)
|
||||
m_timer.setInterval (100 /*hover time*/);
|
||||
m_timer.setSingleShot (true);
|
||||
connect (&m_timer, SIGNAL (timeout ()), this, SLOT (timeout ()));
|
||||
#endif
|
||||
|
||||
mp_view->annotations_changed_event.add (this, &Service::annotations_changed);
|
||||
}
|
||||
|
||||
|
|
@ -1809,9 +1819,36 @@ Service::mouse_double_click_event (const db::DPoint & /*p*/, unsigned int button
|
|||
return false;
|
||||
}
|
||||
|
||||
lay::TwoPointSnapToObjectResult
|
||||
Service::auto_measure (const db::DPoint &p, lay::angle_constraint_type ac, const ant::Template &tpl)
|
||||
{
|
||||
// for auto-metric we need some cutline constraint - any or global won't do.
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = tpl.angle_constraint ();
|
||||
}
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = m_snap_mode;
|
||||
}
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = lay::AC_Diagonal;
|
||||
}
|
||||
|
||||
db::DVector g;
|
||||
if (m_grid_snap) {
|
||||
g = db::DVector (m_grid, m_grid);
|
||||
}
|
||||
|
||||
double snap_range = ui ()->mouse_event_trans ().inverted ().ctrans (m_snap_range);
|
||||
snap_range *= 0.5;
|
||||
|
||||
return lay::obj_snap2 (mp_view, p, g, ac, snap_range, snap_range * 1000.0);
|
||||
}
|
||||
|
||||
bool
|
||||
Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
||||
{
|
||||
hover_reset ();
|
||||
|
||||
if (prio && (buttons & lay::LeftButton) != 0) {
|
||||
|
||||
const ant::Template &tpl = current_template ();
|
||||
|
|
@ -1852,27 +1889,7 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
|
||||
} else if (tpl.mode () == ant::Template::RulerAutoMetric) {
|
||||
|
||||
// for auto-metric we need some cutline constraint - any or global won't do.
|
||||
lay::angle_constraint_type ac = ac_from_buttons (buttons);
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = tpl.angle_constraint ();
|
||||
}
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = m_snap_mode;
|
||||
}
|
||||
if (ac == lay::AC_Global) {
|
||||
ac = lay::AC_Diagonal;
|
||||
}
|
||||
|
||||
db::DVector g;
|
||||
if (m_grid_snap) {
|
||||
g = db::DVector (m_grid, m_grid);
|
||||
}
|
||||
|
||||
double snap_range = ui ()->mouse_event_trans ().inverted ().ctrans (m_snap_range);
|
||||
snap_range *= 0.5;
|
||||
|
||||
lay::TwoPointSnapToObjectResult ee = lay::obj_snap2 (mp_view, p, g, ac, snap_range, snap_range * 1000.0);
|
||||
lay::TwoPointSnapToObjectResult ee = auto_measure (p, ac_from_buttons (buttons), tpl);
|
||||
if (ee.any) {
|
||||
|
||||
// begin the transaction
|
||||
|
|
@ -1893,6 +1910,29 @@ Service::mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio
|
|||
|
||||
}
|
||||
|
||||
} else if (tpl.mode () == ant::Template::RulerAutoMetricEdge) {
|
||||
|
||||
lay::PointSnapToObjectResult snap_details = snap1_details (p, true);
|
||||
if (snap_details.object_snap == lay::PointSnapToObjectResult::ObjectEdge) {
|
||||
|
||||
// begin the transaction
|
||||
if (manager ()) {
|
||||
tl_assert (! manager ()->transacting ());
|
||||
manager ()->transaction (tl::to_string (tr ("Create ruler")));
|
||||
}
|
||||
|
||||
m_current = ant::Object (snap_details.object_ref.p1 (), snap_details.object_ref.p2 (), 0, tpl);
|
||||
show_message ();
|
||||
|
||||
insert_ruler (m_current, true);
|
||||
|
||||
// end the transaction
|
||||
if (manager ()) {
|
||||
manager ()->commit ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
m_p1 = snap1 (p, m_obj_snap && tpl.snap ()).second;
|
||||
|
|
@ -1968,21 +2008,33 @@ Service::create_measure_ruler (const db::DPoint &pt, lay::angle_constraint_type
|
|||
bool
|
||||
Service::mouse_move_event (const db::DPoint &p, unsigned int buttons, bool prio)
|
||||
{
|
||||
if (prio) {
|
||||
if (! prio) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lay::PointSnapToObjectResult snap_details;
|
||||
if (m_drawing) {
|
||||
snap_details = snap2_details (m_p1, p, mp_active_ruler->ruler (), ac_from_buttons (buttons));
|
||||
} else {
|
||||
const ant::Template &tpl = current_template ();
|
||||
snap_details = snap1_details (p, m_obj_snap && tpl.snap ());
|
||||
}
|
||||
if (! m_drawing && m_mouse_in_window && view ()->transient_selection_mode ()) {
|
||||
|
||||
mouse_cursor_from_snap_details (snap_details);
|
||||
// Restart hover timer
|
||||
m_hover_wait = true;
|
||||
#if defined(HAVE_QT)
|
||||
m_timer.start ();
|
||||
#endif
|
||||
m_hover_point = p;
|
||||
m_hover_buttons = buttons;
|
||||
|
||||
}
|
||||
|
||||
if (m_drawing && prio) {
|
||||
lay::PointSnapToObjectResult snap_details;
|
||||
if (m_drawing) {
|
||||
snap_details = snap2_details (m_p1, p, mp_active_ruler->ruler (), ac_from_buttons (buttons));
|
||||
} else {
|
||||
const ant::Template &tpl = current_template ();
|
||||
snap_details = snap1_details (p, m_obj_snap && tpl.snap () && (tpl.mode () != ant::Template::RulerAutoMetricEdge || ! view ()->transient_selection_mode ()));
|
||||
}
|
||||
|
||||
mouse_cursor_from_snap_details (snap_details);
|
||||
|
||||
if (m_drawing) {
|
||||
|
||||
set_cursor (lay::Cursor::cross);
|
||||
|
||||
|
|
@ -2284,6 +2336,84 @@ Service::click_proximity (const db::DPoint &pos, lay::Editable::SelectionMode mo
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Service::enter_event (bool /*prio*/)
|
||||
{
|
||||
m_mouse_in_window = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
Service::leave_event (bool)
|
||||
{
|
||||
m_mouse_in_window = false;
|
||||
hover_reset ();
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
Service::hover_reset ()
|
||||
{
|
||||
if (m_hover_wait) {
|
||||
#if defined(HAVE_QT)
|
||||
m_timer.stop ();
|
||||
#endif
|
||||
m_hover_wait = false;
|
||||
}
|
||||
if (m_hover) {
|
||||
// as we use the transient selection for the hover ruler, we have to remove it here
|
||||
clear_transient_selection ();
|
||||
m_hover = false;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_QT)
|
||||
void
|
||||
Service::timeout ()
|
||||
{
|
||||
m_hover_wait = false;
|
||||
m_hover = true;
|
||||
|
||||
// as we use the transient selection for the hover ruler, we have to remove it here
|
||||
clear_transient_selection ();
|
||||
|
||||
// transiently create an auto-metric ruler if requested
|
||||
|
||||
ant::Object *ruler = 0;
|
||||
|
||||
const ant::Template &tpl = current_template ();
|
||||
if (tpl.mode () == ant::Template::RulerAutoMetric) {
|
||||
|
||||
lay::TwoPointSnapToObjectResult ee = auto_measure (m_hover_point, ac_from_buttons (m_hover_buttons), tpl);
|
||||
if (ee.any) {
|
||||
m_current = ant::Object (ee.first, ee.second, 0, tpl);
|
||||
ruler = &m_current;
|
||||
}
|
||||
|
||||
} else if (tpl.mode () == ant::Template::RulerAutoMetricEdge) {
|
||||
|
||||
lay::PointSnapToObjectResult snap_details = snap1_details (m_hover_point, true);
|
||||
if (snap_details.object_snap == lay::PointSnapToObjectResult::ObjectEdge) {
|
||||
m_current = ant::Object (snap_details.object_ref.p1 (), snap_details.object_ref.p2 (), 0, tpl);
|
||||
ruler = &m_current;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ruler) {
|
||||
|
||||
// HINT: there is no special style for "transient selection on rulers"
|
||||
mp_transient_ruler = new ant::View (this, ruler, true /*not selected*/);
|
||||
|
||||
if (! editables ()->has_selection ()) {
|
||||
display_status (true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
Service::transient_select (const db::DPoint &pos)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -39,6 +39,11 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#if defined (HAVE_QT)
|
||||
# include <QTimer>
|
||||
# include <QObject>
|
||||
#endif
|
||||
|
||||
namespace ant {
|
||||
|
||||
class LayoutViewBase;
|
||||
|
|
@ -177,12 +182,19 @@ private:
|
|||
|
||||
// -------------------------------------------------------------
|
||||
|
||||
class ANT_PUBLIC Service
|
||||
: public lay::EditorServiceBase,
|
||||
class ANT_PUBLIC Service :
|
||||
#if defined (HAVE_QT)
|
||||
public QObject,
|
||||
#endif
|
||||
public lay::EditorServiceBase,
|
||||
public lay::Drawing,
|
||||
public db::Object
|
||||
{
|
||||
public:
|
||||
#if defined (HAVE_QT)
|
||||
Q_OBJECT
|
||||
#endif
|
||||
|
||||
public:
|
||||
typedef lay::AnnotationShapes::iterator obj_iterator;
|
||||
|
||||
/**
|
||||
|
|
@ -341,6 +353,21 @@ public:
|
|||
*/
|
||||
virtual db::DBox selection_bbox ();
|
||||
|
||||
/**
|
||||
* @brief Implementation of the editables API
|
||||
*/
|
||||
virtual bool enter_event (bool);
|
||||
|
||||
/**
|
||||
* @brief Implementation of the editables API
|
||||
*/
|
||||
virtual bool leave_event (bool);
|
||||
|
||||
/**
|
||||
* @brief Implementation of the editables API
|
||||
*/
|
||||
virtual void hover_reset ();
|
||||
|
||||
/**
|
||||
* @brief Transform the selection (reimplementation of lay::Editable interface)
|
||||
*/
|
||||
|
|
@ -506,6 +533,11 @@ public:
|
|||
*/
|
||||
tl::Event annotation_selection_changed_event;
|
||||
|
||||
#if defined (HAVE_QT)
|
||||
public slots:
|
||||
void timeout ();
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Ruler display and snapping configuration
|
||||
tl::Color m_color;
|
||||
|
|
@ -551,10 +583,22 @@ private:
|
|||
std::vector<ant::Template> m_ruler_templates;
|
||||
unsigned int m_current_template;
|
||||
|
||||
// Hover detector
|
||||
bool m_hover;
|
||||
bool m_hover_wait;
|
||||
db::DPoint m_hover_point;
|
||||
unsigned int m_hover_buttons;
|
||||
#if defined (HAVE_QT)
|
||||
QTimer m_timer;
|
||||
#endif
|
||||
|
||||
bool m_mouse_in_window;
|
||||
|
||||
std::pair<bool, db::DPoint> snap1 (const db::DPoint &p, bool obj_snap);
|
||||
lay::PointSnapToObjectResult snap1_details (const db::DPoint &p, bool obj_snap);
|
||||
std::pair<bool, db::DPoint> snap2 (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
||||
lay::PointSnapToObjectResult snap2_details (const db::DPoint &p1, const db::DPoint &p2, const ant::Object *obj, lay::angle_constraint_type ac);
|
||||
lay::TwoPointSnapToObjectResult auto_measure (const db::DPoint &p, lay::angle_constraint_type ac, const ant::Template &tpl);
|
||||
|
||||
const ant::Template ¤t_template () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -64,15 +64,20 @@ public:
|
|||
*/
|
||||
RulerAutoMetric = 2,
|
||||
|
||||
/**
|
||||
* @brief The ruler is auto-metric along an edge: a single click will place a ruler and the ruler will extend to the edge below
|
||||
*/
|
||||
RulerAutoMetricEdge = 3,
|
||||
|
||||
/**
|
||||
* @brief The ruler an angle type (two segments, three mouse clicks) for angle and circle radius measurements
|
||||
*/
|
||||
RulerThreeClicks = 3,
|
||||
RulerThreeClicks = 4,
|
||||
|
||||
/**
|
||||
* @brief The ruler is a multi-segment type
|
||||
*/
|
||||
RulerMultiSegment = 4
|
||||
RulerMultiSegment = 5
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -434,6 +434,11 @@ static int ruler_mode_auto_metric ()
|
|||
return ant::Template::RulerAutoMetric;
|
||||
}
|
||||
|
||||
static int ruler_mode_auto_metric_edge ()
|
||||
{
|
||||
return ant::Template::RulerAutoMetricEdge;
|
||||
}
|
||||
|
||||
static int ruler_mode_three_clicks ()
|
||||
{
|
||||
return ant::Template::RulerThreeClicks;
|
||||
|
|
@ -525,6 +530,12 @@ gsi::Class<AnnotationRef> decl_Annotation (decl_BasicAnnotation, "lay", "Annotat
|
|||
"\n"
|
||||
"This constant has been introduced in version 0.25"
|
||||
) +
|
||||
gsi::method ("RulerModeAutoMetricEdge", &gsi::ruler_mode_auto_metric_edge,
|
||||
"@brief Specifies edge-sensitive auto-metric ruler mode for the \\register_template method\n"
|
||||
"In auto-metric mode, a ruler can be placed with a single click and p1/p2 will be determined from the edge it is placed on.\n"
|
||||
"\n"
|
||||
"This constant has been introduced in version 0.29"
|
||||
) +
|
||||
gsi::method ("RulerThreeClicks", &gsi::ruler_mode_three_clicks,
|
||||
"@brief Specifies three-click ruler mode for the \\register_template method\n"
|
||||
"In this ruler mode, two segments are created for angle and circle radius measurements. Three mouse clicks are required.\n"
|
||||
|
|
|
|||
|
|
@ -154,6 +154,10 @@ CommonReaderBase::rename_cell (db::Layout &layout, size_t id, const std::string
|
|||
common_reader_error (tl::sprintf (tl::to_string (tr ("Cell named %s with ID %ld was already given name %s")), cn, id, iid->second.first));
|
||||
}
|
||||
|
||||
if (iname != m_name_map.end () && iname->second.first != null_id && iname->second.first != id) {
|
||||
common_reader_error (tl::sprintf (tl::to_string (tr ("Same cell name %s, but different IDs: %ld and %ld")), cn, id, iname->second.first));
|
||||
}
|
||||
|
||||
if (iid != m_id_map.end () && iname != m_name_map.end ()) {
|
||||
|
||||
if (iname->second.second != iid->second.second) {
|
||||
|
|
|
|||
|
|
@ -1566,23 +1566,26 @@ compute_rounded (const db::DPolygon &polygon, double rinner, double router, unsi
|
|||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Implementation of AreaMap
|
||||
// Implementation of area_map
|
||||
|
||||
AreaMap::AreaMap ()
|
||||
template <class C>
|
||||
area_map<C>::area_map ()
|
||||
: m_nx (0), m_ny (0)
|
||||
{
|
||||
mp_av = 0;
|
||||
}
|
||||
|
||||
AreaMap::AreaMap (const AreaMap &other)
|
||||
template <class C>
|
||||
area_map<C>::area_map (const area_map &other)
|
||||
: m_nx (0), m_ny (0)
|
||||
{
|
||||
mp_av = 0;
|
||||
operator= (other);
|
||||
}
|
||||
|
||||
AreaMap &
|
||||
AreaMap::operator= (const AreaMap &other)
|
||||
template <class C>
|
||||
area_map<C> &
|
||||
area_map<C>::operator= (const area_map &other)
|
||||
{
|
||||
if (this != &other) {
|
||||
// TODO: this could be copy on write
|
||||
|
|
@ -1594,21 +1597,24 @@ AreaMap::operator= (const AreaMap &other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
AreaMap::AreaMap (const db::Point &p0, const db::Vector &d, size_t nx, size_t ny)
|
||||
template <class C>
|
||||
area_map<C>::area_map (const area_map::point_type &p0, const area_map::vector_type &d, size_t nx, size_t ny)
|
||||
: m_p0 (p0), m_d (d), m_p (d), m_nx (nx), m_ny (ny)
|
||||
{
|
||||
mp_av = new area_type [nx * ny];
|
||||
clear ();
|
||||
}
|
||||
|
||||
AreaMap::AreaMap (const db::Point &p0, const db::Vector &d, const db::Vector &p, size_t nx, size_t ny)
|
||||
template <class C>
|
||||
area_map<C>::area_map (const area_map::point_type &p0, const area_map::vector_type &d, const area_map::vector_type &p, size_t nx, size_t ny)
|
||||
: m_p0 (p0), m_d (d), m_p (std::min (d.x (), p.x ()), std::min (d.y (), p.y ())), m_nx (nx), m_ny (ny)
|
||||
{
|
||||
mp_av = new area_type [nx * ny];
|
||||
clear ();
|
||||
}
|
||||
|
||||
AreaMap::~AreaMap ()
|
||||
template <class C>
|
||||
area_map<C>::~area_map ()
|
||||
{
|
||||
if (mp_av) {
|
||||
delete[] mp_av;
|
||||
|
|
@ -1616,18 +1622,20 @@ AreaMap::~AreaMap ()
|
|||
mp_av = 0;
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void
|
||||
AreaMap::reinitialize (const db::Point &p0, const db::Vector &d, size_t nx, size_t ny)
|
||||
area_map<C>::reinitialize (const area_map::point_type &p0, const area_map::vector_type &d, size_t nx, size_t ny)
|
||||
{
|
||||
reinitialize (p0, d, d, nx, ny);
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void
|
||||
AreaMap::reinitialize (const db::Point &p0, const db::Vector &d, const db::Vector &p, size_t nx, size_t ny)
|
||||
area_map<C>::reinitialize (const area_map::point_type &p0, const area_map::vector_type &d, const area_map::vector_type &p, size_t nx, size_t ny)
|
||||
{
|
||||
m_p0 = p0;
|
||||
m_d = d;
|
||||
m_p = db::Vector (std::min (d.x (), p.x ()), std::min (d.y (), p.y ()));
|
||||
m_p = vector_type (std::min (d.x (), p.x ()), std::min (d.y (), p.y ()));
|
||||
|
||||
if (nx != m_nx || ny != m_ny) {
|
||||
|
||||
|
|
@ -1645,8 +1653,9 @@ AreaMap::reinitialize (const db::Point &p0, const db::Vector &d, const db::Vecto
|
|||
clear ();
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void
|
||||
AreaMap::clear ()
|
||||
area_map<C>::clear ()
|
||||
{
|
||||
if (mp_av) {
|
||||
area_type *a = mp_av;
|
||||
|
|
@ -1656,8 +1665,9 @@ AreaMap::clear ()
|
|||
}
|
||||
}
|
||||
|
||||
template <class C>
|
||||
void
|
||||
AreaMap::swap (AreaMap &other)
|
||||
area_map<C>::swap (area_map &other)
|
||||
{
|
||||
std::swap (m_p0, other.m_p0);
|
||||
std::swap (m_d, other.m_d);
|
||||
|
|
@ -1667,8 +1677,9 @@ AreaMap::swap (AreaMap &other)
|
|||
std::swap (mp_av, other.mp_av);
|
||||
}
|
||||
|
||||
AreaMap::area_type
|
||||
AreaMap::total_area () const
|
||||
template <class C>
|
||||
typename area_map<C>::area_type
|
||||
area_map<C>::total_area () const
|
||||
{
|
||||
area_type asum = 0;
|
||||
if (mp_av) {
|
||||
|
|
@ -1680,16 +1691,21 @@ AreaMap::total_area () const
|
|||
return asum;
|
||||
}
|
||||
|
||||
db::Box
|
||||
AreaMap::bbox () const
|
||||
template <class C>
|
||||
typename area_map<C>::box_type
|
||||
area_map<C>::bbox () const
|
||||
{
|
||||
if (m_nx == 0 || m_ny == 0) {
|
||||
return db::Box ();
|
||||
return box_type ();
|
||||
} else {
|
||||
return db::Box (m_p0, m_p0 + db::Vector (db::Coord (m_nx - 1) * m_d.x () + m_p.x (), db::Coord (m_ny - 1) * m_d.y () + m_p.y ()));
|
||||
return box_type (m_p0, m_p0 + vector_type (C (m_nx - 1) * m_d.x () + m_p.x (), C (m_ny - 1) * m_d.y () + m_p.y ()));
|
||||
}
|
||||
}
|
||||
|
||||
// explicit instantiations
|
||||
template class area_map<db::Coord>;
|
||||
template class area_map<db::DCoord>;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Implementation of rasterize
|
||||
|
||||
|
|
@ -1707,29 +1723,69 @@ static bool edge_is_partially_left_of (const db::Edge &e, const db::Edge &e_orig
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
||||
static bool edge_is_partially_left_of (const db::DEdge &e, const db::DEdge &e_original, db::DCoord x)
|
||||
{
|
||||
typedef db::AreaMap::area_type area_type;
|
||||
db::Box box = am.bbox ();
|
||||
db::Box pbox = polygon.box ();
|
||||
DCoord xmin = db::edge_xmin (e);
|
||||
if (db::coord_traits<db::DCoord>::less (xmin, x)) {
|
||||
return true;
|
||||
} else if (db::coord_traits<db::DCoord>::equal (xmin, x) && ! db::coord_traits<db::DCoord>::equal (e_original.dx (), 0)) {
|
||||
// the skew edge is cut partially rendering a straight vertical line (due to rounding)
|
||||
// which we will count as "left of"
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t npixels_floor (db::Coord d, db::Coord p)
|
||||
{
|
||||
return size_t (std::max (db::Coord (0), d / p));
|
||||
}
|
||||
|
||||
static size_t npixels_ceil (db::Coord d, db::Coord p)
|
||||
{
|
||||
return size_t (std::max (db::Coord (0), (d + p - 1) / p));
|
||||
}
|
||||
|
||||
static size_t npixels_floor (db::DCoord d, db::DCoord p)
|
||||
{
|
||||
return size_t (std::max (db::DCoord (0), floor (d / p + db::epsilon)));
|
||||
}
|
||||
|
||||
static size_t npixels_ceil (db::DCoord d, db::DCoord p)
|
||||
{
|
||||
return size_t (std::max (db::DCoord (0), ceil (d / p - db::epsilon)));
|
||||
}
|
||||
|
||||
|
||||
template <class C>
|
||||
static
|
||||
bool
|
||||
rasterize_impl (const db::polygon<C> &polygon, db::area_map<C> &am)
|
||||
{
|
||||
typedef typename db::area_map<C>::area_type area_type;
|
||||
typedef db::box<C> box_type;
|
||||
typedef db::edge<C> edge_type;
|
||||
|
||||
box_type box = am.bbox ();
|
||||
box_type pbox = polygon.box ();
|
||||
|
||||
// check if the polygon overlaps the rasterization area. Otherwise, we simply do nothing.
|
||||
if (! pbox.overlaps (box)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
db::Coord ymin = box.bottom (), ymax = box.top ();
|
||||
db::Coord dy = am.d ().y (), dx = am.d ().x ();
|
||||
db::Coord py = am.p ().y (), px = am.p ().x ();
|
||||
db::Coord y0 = am.p0 ().y (), x0 = am.p0 ().x ();
|
||||
C ymin = box.bottom (), ymax = box.top ();
|
||||
C dy = am.d ().y (), dx = am.d ().x ();
|
||||
C py = am.p ().y (), px = am.p ().x ();
|
||||
C y0 = am.p0 ().y (), x0 = am.p0 ().x ();
|
||||
size_t ny = am.ny (), nx = am.nx ();
|
||||
|
||||
size_t iy0 = std::min (ny, size_t (std::max (db::Coord (0), (pbox.bottom () - am.p0 ().y ()) / am.d ().y ())));
|
||||
size_t iy1 = std::min (ny, size_t (std::max (db::Coord (0), (pbox.top () - am.p0 ().y () + am.d ().y () - 1) / am.d ().y ())));
|
||||
size_t iy0 = std::min (ny, npixels_floor (pbox.bottom () - am.p0 ().y (), am.d ().y ()));
|
||||
size_t iy1 = std::min (ny, npixels_ceil (pbox.top () - am.p0 ().y (), am.d ().y ()));
|
||||
|
||||
size_t ix0 = std::min (nx, size_t (std::max (db::Coord (0), (pbox.left () - am.p0 ().x ()) / am.d ().x ())));
|
||||
size_t ix1 = std::min (nx, size_t (std::max (db::Coord (0), (pbox.right () - am.p0 ().x () + am.d ().x () - 1) / am.d ().x ())));
|
||||
size_t ix0 = std::min (nx, npixels_floor (pbox.left () - am.p0 ().x (), am.d ().x ()));
|
||||
size_t ix1 = std::min (nx, npixels_ceil (pbox.right () - am.p0 ().x (), am.d ().x ()));
|
||||
|
||||
// no scanning required (i.e. degenerated polygon) -> do nothing
|
||||
if (iy0 == iy1 || ix0 == ix1) {
|
||||
|
|
@ -1738,26 +1794,26 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
|
||||
// collect edges
|
||||
size_t n = 0;
|
||||
for (db::Polygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
|
||||
for (typename db::polygon<C>::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
|
||||
if ((*e).dy () != 0 && db::edge_ymax (*e) > ymin && db::edge_ymin (*e) < ymax) {
|
||||
++n;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector <db::Edge> edges;
|
||||
std::vector <edge_type> edges;
|
||||
edges.reserve (n);
|
||||
for (db::Polygon::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
|
||||
for (typename db::polygon<C>::polygon_edge_iterator e = polygon.begin_edge (); ! e.at_end (); ++e) {
|
||||
if ((*e).dy () != 0 && db::edge_ymax (*e) > ymin && db::edge_ymin (*e) < ymax) {
|
||||
edges.push_back (*e);
|
||||
}
|
||||
}
|
||||
|
||||
// sort edges
|
||||
std::sort (edges.begin (), edges.end (), db::edge_ymin_compare<db::Coord> ());
|
||||
std::sort (edges.begin (), edges.end (), db::edge_ymin_compare<C> ());
|
||||
|
||||
std::vector <db::Edge>::iterator c = edges.begin ();
|
||||
typename std::vector <edge_type>::iterator c = edges.begin ();
|
||||
|
||||
db::Coord y = y0 + dy * db::Coord (iy0);
|
||||
C y = y0 + dy * C (iy0);
|
||||
|
||||
while (c != edges.end () && db::edge_ymax (*c) <= y) {
|
||||
++c;
|
||||
|
|
@ -1767,36 +1823,36 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
return false;
|
||||
}
|
||||
|
||||
std::vector <db::Edge>::iterator f = c;
|
||||
typename std::vector <edge_type>::iterator f = c;
|
||||
|
||||
for (size_t iy = iy0; iy < iy1; ++iy) {
|
||||
|
||||
db::Coord yy = y + py;
|
||||
C yy = y + py;
|
||||
while (f != edges.end () && db::edge_ymin (*f) < yy) {
|
||||
++f;
|
||||
}
|
||||
|
||||
std::sort (c, f, db::edge_xmin_compare <db::Coord> ());
|
||||
std::sort (c, f, db::edge_xmin_compare <C> ());
|
||||
|
||||
db::Coord x = x0 + dx * db::Coord (ix0);
|
||||
db::Coord xl = pbox.left ();
|
||||
C x = x0 + dx * C (ix0);
|
||||
C xl = pbox.left ();
|
||||
area_type a = 0;
|
||||
|
||||
std::vector <db::Edge>::iterator cc = c;
|
||||
typename std::vector <edge_type>::iterator cc = c;
|
||||
|
||||
while (cc != edges.end () && cc != f && db::edge_xmax (*cc) <= x) {
|
||||
db::Coord y1 = std::max (y, std::min (yy, cc->p1 ().y ()));
|
||||
db::Coord y2 = std::max (y, std::min (yy, cc->p2 ().y ()));
|
||||
C y1 = std::max (y, std::min (yy, cc->p1 ().y ()));
|
||||
C y2 = std::max (y, std::min (yy, cc->p2 ().y ()));
|
||||
a += area_type (px) * area_type (y2 - y1);
|
||||
++cc;
|
||||
}
|
||||
|
||||
std::vector <db::Edge>::iterator ff = cc;
|
||||
typename std::vector <edge_type>::iterator ff = cc;
|
||||
|
||||
for (size_t ix = ix0; ix < ix1; ++ix) {
|
||||
|
||||
db::Coord xx = x + px;
|
||||
db::Coord xxx = x + dx;
|
||||
C xx = x + px;
|
||||
C xxx = x + dx;
|
||||
|
||||
// TODO: edge_xmin_at_interval(y, yy) and edge_xmax.. would be more efficient in the
|
||||
// all-angle case. However, it is crucial that the edge clipping produces
|
||||
|
|
@ -1807,7 +1863,7 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
++ff;
|
||||
}
|
||||
|
||||
std::vector <db::Edge>::iterator fff = ff;
|
||||
typename std::vector <edge_type>::iterator fff = ff;
|
||||
|
||||
if (xx < xxx) {
|
||||
while (fff != f && db::edge_xmin (*fff) < xxx) {
|
||||
|
|
@ -1818,11 +1874,11 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
if (xl < x) {
|
||||
|
||||
// consider all edges or parts of those left of the first cell
|
||||
db::Box left (xl, y, x, yy);
|
||||
box_type left (xl, y, x, yy);
|
||||
|
||||
for (std::vector <db::Edge>::iterator e = cc; e != ff; ++e) {
|
||||
for (typename std::vector <edge_type>::iterator e = cc; e != ff; ++e) {
|
||||
|
||||
std::pair<bool, db::Edge> ec = e->clipped (left);
|
||||
std::pair<bool, edge_type> ec = e->clipped (left);
|
||||
if (ec.first && edge_is_partially_left_of (ec.second, *e, x)) {
|
||||
a += area_type (ec.second.dy ()) * area_type (px);
|
||||
}
|
||||
|
|
@ -1835,11 +1891,11 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
|
||||
if (dx == py) {
|
||||
|
||||
db::Box cell (x, y, xx, yy);
|
||||
box_type cell (x, y, xx, yy);
|
||||
|
||||
for (std::vector <db::Edge>::iterator e = cc; e != ff; ++e) {
|
||||
for (typename std::vector <edge_type>::iterator e = cc; e != ff; ++e) {
|
||||
|
||||
std::pair<bool, db::Edge> ec = e->clipped (cell);
|
||||
std::pair<bool, edge_type> ec = e->clipped (cell);
|
||||
if (ec.first && edge_is_partially_left_of (ec.second, *e, xx)) {
|
||||
aa += (area_type (ec.second.dy ()) * area_type (2 * xx - (ec.second.p2 ().x () + ec.second.p1 ().x ()))) / 2;
|
||||
a += area_type (ec.second.dy ()) * area_type (px);
|
||||
|
|
@ -1849,22 +1905,22 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
|
||||
} else {
|
||||
|
||||
db::Box cell (x, y, xx, yy);
|
||||
box_type cell (x, y, xx, yy);
|
||||
|
||||
for (std::vector <db::Edge>::iterator e = cc; e != ff; ++e) {
|
||||
for (typename std::vector <edge_type>::iterator e = cc; e != ff; ++e) {
|
||||
|
||||
std::pair<bool, db::Edge> ec = e->clipped (cell);
|
||||
std::pair<bool, edge_type> ec = e->clipped (cell);
|
||||
if (ec.first && edge_is_partially_left_of (ec.second, *e, xx)) {
|
||||
aa += (area_type (ec.second.dy ()) * area_type (2 * xx - (ec.second.p2 ().x () + ec.second.p1 ().x ()))) / 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
db::Box wide_cell (x, y, x + dx, yy);
|
||||
box_type wide_cell (x, y, x + dx, yy);
|
||||
|
||||
for (std::vector <db::Edge>::iterator e = cc; e != fff; ++e) {
|
||||
for (typename std::vector <edge_type>::iterator e = cc; e != fff; ++e) {
|
||||
|
||||
std::pair<bool, db::Edge> wide_ec = e->clipped (wide_cell);
|
||||
std::pair<bool, edge_type> wide_ec = e->clipped (wide_cell);
|
||||
if (wide_ec.first && edge_is_partially_left_of (wide_ec.second, *e, x + dx)) {
|
||||
a += area_type (wide_ec.second.dy ()) * area_type (px);
|
||||
}
|
||||
|
|
@ -1880,7 +1936,7 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
|
||||
ff = fff;
|
||||
|
||||
for (std::vector <db::Edge>::iterator ccx = cc; ccx != ff; ++ccx) {
|
||||
for (typename std::vector <edge_type>::iterator ccx = cc; ccx != ff; ++ccx) {
|
||||
if (db::edge_xmax (*ccx) <= x) {
|
||||
std::swap (*ccx, *cc);
|
||||
++cc;
|
||||
|
|
@ -1898,7 +1954,7 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
|
||||
y = yy;
|
||||
|
||||
for (std::vector <db::Edge>::iterator cx = c; cx != f; ++cx) {
|
||||
for (typename std::vector <edge_type>::iterator cx = c; cx != f; ++cx) {
|
||||
if (db::edge_ymax (*cx) <= y) {
|
||||
std::swap (*cx, *c);
|
||||
++c;
|
||||
|
|
@ -1910,6 +1966,18 @@ rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
rasterize (const db::Polygon &polygon, db::AreaMap &am)
|
||||
{
|
||||
return rasterize_impl<db::Coord> (polygon, am);
|
||||
}
|
||||
|
||||
bool
|
||||
rasterize (const db::DPolygon &polygon, db::DAreaMap &am)
|
||||
{
|
||||
return rasterize_impl<db::DCoord> (polygon, am);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Implementation of Minkowski sum
|
||||
|
||||
|
|
|
|||
|
|
@ -493,55 +493,59 @@ bool DB_PUBLIC is_non_orientable_polygon (const db::Polygon &poly, std::vector<d
|
|||
* It is used for example by the rasterize function to collect area values
|
||||
* on a per-pixel basis.
|
||||
*/
|
||||
class DB_PUBLIC AreaMap
|
||||
template <class C>
|
||||
class DB_PUBLIC area_map
|
||||
{
|
||||
public:
|
||||
typedef db::coord_traits<db::Coord>::area_type area_type;
|
||||
typedef typename db::coord_traits<C>::area_type area_type;
|
||||
typedef db::point<C> point_type;
|
||||
typedef db::vector<C> vector_type;
|
||||
typedef db::box<C> box_type;
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
AreaMap ();
|
||||
area_map ();
|
||||
|
||||
/**
|
||||
* @brief Copy constructor
|
||||
*/
|
||||
AreaMap (const AreaMap &);
|
||||
area_map (const area_map &);
|
||||
|
||||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
AreaMap (const db::Point &p0, const db::Vector &d, size_t nx, size_t ny);
|
||||
area_map (const point_type &p0, const vector_type &d, size_t nx, size_t ny);
|
||||
|
||||
/**
|
||||
* @brief Constructor with pixel size
|
||||
*/
|
||||
AreaMap (const db::Point &p0, const db::Vector &d, const db::Vector &p, size_t nx, size_t ny);
|
||||
area_map (const point_type &p0, const vector_type &d, const vector_type &p, size_t nx, size_t ny);
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~AreaMap ();
|
||||
~area_map ();
|
||||
|
||||
/**
|
||||
* @brief Assignment
|
||||
*/
|
||||
AreaMap &operator= (const AreaMap &);
|
||||
area_map &operator= (const area_map &);
|
||||
|
||||
/**
|
||||
* @brief Reinitialize
|
||||
*/
|
||||
void reinitialize (const db::Point &p0, const db::Vector &d, size_t nx, size_t ny);
|
||||
void reinitialize (const point_type &p0, const vector_type &d, size_t nx, size_t ny);
|
||||
|
||||
/**
|
||||
* @brief Reinitialize with pixel size
|
||||
*/
|
||||
void reinitialize (const db::Point &p0, const db::Vector &d, const db::Vector &p, size_t nx, size_t ny);
|
||||
void reinitialize (const point_type &p0, const vector_type &d, const vector_type &p, size_t nx, size_t ny);
|
||||
|
||||
/**
|
||||
* @brief Swap of two maps
|
||||
*/
|
||||
void swap (AreaMap &other);
|
||||
void swap (area_map &other);
|
||||
|
||||
/**
|
||||
* @brief Get the area of one pixel
|
||||
|
|
@ -578,7 +582,7 @@ public:
|
|||
/**
|
||||
* @brief The origin
|
||||
*/
|
||||
const db::Point &p0 () const
|
||||
const point_type &p0 () const
|
||||
{
|
||||
return m_p0;
|
||||
}
|
||||
|
|
@ -586,7 +590,7 @@ public:
|
|||
/**
|
||||
* @brief Move the origin
|
||||
*/
|
||||
void move (const db::Vector &d)
|
||||
void move (const vector_type &d)
|
||||
{
|
||||
m_p0 += d;
|
||||
}
|
||||
|
|
@ -594,7 +598,7 @@ public:
|
|||
/**
|
||||
* @brief The per-pixel displacement vector (pixel size)
|
||||
*/
|
||||
const db::Vector &d () const
|
||||
const vector_type &d () const
|
||||
{
|
||||
return m_d;
|
||||
}
|
||||
|
|
@ -602,7 +606,7 @@ public:
|
|||
/**
|
||||
* @brief The pixel size (must be less than d)
|
||||
*/
|
||||
const db::Vector &p () const
|
||||
const vector_type &p () const
|
||||
{
|
||||
return m_p;
|
||||
}
|
||||
|
|
@ -610,7 +614,7 @@ public:
|
|||
/**
|
||||
* @brief Compute the bounding box of the area map
|
||||
*/
|
||||
db::Box bbox () const;
|
||||
box_type bbox () const;
|
||||
|
||||
/**
|
||||
* @brief Compute the total area
|
||||
|
|
@ -632,12 +636,15 @@ public:
|
|||
|
||||
private:
|
||||
area_type *mp_av;
|
||||
db::Point m_p0;
|
||||
db::Vector m_d;
|
||||
db::Vector m_p;
|
||||
point_type m_p0;
|
||||
vector_type m_d;
|
||||
vector_type m_p;
|
||||
size_t m_nx, m_ny;
|
||||
};
|
||||
|
||||
typedef area_map<db::Coord> AreaMap;
|
||||
typedef area_map<db::DCoord> DAreaMap;
|
||||
|
||||
/**
|
||||
* @brief Rasterize the polygon into the given area map
|
||||
*
|
||||
|
|
@ -648,6 +655,16 @@ private:
|
|||
*/
|
||||
bool DB_PUBLIC rasterize (const db::Polygon &polygon, db::AreaMap &am);
|
||||
|
||||
/**
|
||||
* @brief Rasterize the polygon into the given area map (double version)
|
||||
*
|
||||
* This will decompose the polygon and produce per-pixel area values for the given
|
||||
* polygon. The area contributions will be added to the given area map.
|
||||
*
|
||||
* Returns a value indicating whether the map will be non-empty.
|
||||
*/
|
||||
bool DB_PUBLIC rasterize (const db::DPolygon &polygon, db::DAreaMap &am);
|
||||
|
||||
/**
|
||||
* @brief Minkowski sum of an edge and a polygon
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -788,6 +788,40 @@ size_dvm (db::Region *region, const db::Vector &dv, unsigned int mode)
|
|||
return *region;
|
||||
}
|
||||
|
||||
static std::vector<std::vector<double> >
|
||||
rasterize2 (const db::Region *region, const db::Point &origin, const db::Vector &pixel_distance, const db::Vector &pixel_size, unsigned int nx, unsigned int ny)
|
||||
{
|
||||
db::DAreaMap am (db::DPoint (origin), db::DVector (pixel_distance), db::DVector (pixel_size), nx, ny);
|
||||
|
||||
auto pi = region->begin ();
|
||||
pi = pi.confined (db::Box (am.bbox ()), false /*not overlapping*/);
|
||||
|
||||
while (! pi.at_end ()) {
|
||||
db::DPolygon dp (*pi);
|
||||
db::rasterize (dp, am);
|
||||
++pi;
|
||||
}
|
||||
|
||||
std::vector<std::vector<double> > result;
|
||||
result.reserve (ny);
|
||||
for (unsigned int y = 0; y < ny; ++y) {
|
||||
result.push_back (std::vector<double> ());
|
||||
std::vector<double> &row = result.back ();
|
||||
row.reserve (nx);
|
||||
for (unsigned int x = 0; x < nx; ++x) {
|
||||
row.push_back (am.get (x, y));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::vector<std::vector<double> >
|
||||
rasterize1 (const db::Region *region, const db::Point &origin, const db::Vector &pixel_size, unsigned int nx, unsigned int ny)
|
||||
{
|
||||
return rasterize2 (region, origin, pixel_size, pixel_size, nx, ny);
|
||||
}
|
||||
|
||||
static db::Point default_origin;
|
||||
|
||||
// provided by gsiDeclDbPolygon.cc:
|
||||
|
|
@ -3095,6 +3129,36 @@ Class<db::Region> decl_Region (decl_dbShapeCollection, "db", "Region",
|
|||
"@brief Converts the region to a string\n"
|
||||
"This version allows specification of the maximum number of polygons contained in the string."
|
||||
) +
|
||||
method_ext ("rasterize", &rasterize1, gsi::arg ("origin"), gsi::arg ("pixel_size"), gsi::arg ("nx"), gsi::arg ("ny"),
|
||||
"@brief A grayscale rasterizer delivering the area covered per pixel\n"
|
||||
"@param origin The lower-left corner of the lowest-left pixel\n"
|
||||
"@param pixel_size The dimension of each pixel (the x component gives the width, the y component the height)\n"
|
||||
"@param nx The number of pixels in horizontal direction\n"
|
||||
"@param ny The number of pixels in vertical direction\n"
|
||||
"The method will create a grayscale, high-resolution density map of a rectangular region.\n"
|
||||
"The scan region is defined by the origin, the pixel size and the number of pixels in horizontal (nx) and\n"
|
||||
"vertical (ny) direction. The resulting array will contain the area covered by polygons from the region\n"
|
||||
"in square database units.\n"
|
||||
"\n"
|
||||
"For non-overlapping polygons, the maximum density value is px*py. Overlapping polygons are counted multiple\n"
|
||||
"times, so the actual values may be larger. If you want overlaps removed, you have to\n"
|
||||
"merge the region before. Merge semantics does not apply for the 'rasterize' method.\n"
|
||||
"\n"
|
||||
"The resulting area values are precise within the limits of double-precision floating point arithmetics.\n"
|
||||
"\n"
|
||||
"A second version exists that allows specifying an active pixel size which is smaller than the\n"
|
||||
"pixel distance hence allowing pixels samples that do not cover the full area, but leave gaps between the pixels.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.29.\n"
|
||||
) +
|
||||
method_ext ("rasterize", &rasterize2, gsi::arg ("origin"), gsi::arg ("pixel_distance"), gsi::arg ("pixel_size"), gsi::arg ("nx"), gsi::arg ("ny"),
|
||||
"@brief A version of 'rasterize' that allows a pixel step distance which is larger than the pixel size\n"
|
||||
"This version behaves like the first variant of 'rasterize', but the pixel distance (pixel-to-pixel step raster)\n"
|
||||
"can be specified separately from the pixel size. Currently, the pixel size must be equal or smaller than the\n"
|
||||
"pixel distance - i.e. the pixels must not overlap.\n"
|
||||
"\n"
|
||||
"This method has been added in version 0.29.\n"
|
||||
) +
|
||||
method ("enable_progress", &db::Region::enable_progress, gsi::arg ("label"),
|
||||
"@brief Enable progress reporting\n"
|
||||
"After calling this method, the region will report the progress through a progress bar while "
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
<title>DRC Reference: Global Functions</title>
|
||||
<keyword name="global"/>
|
||||
<p>
|
||||
Some functions are available on global level and can be used without any object.
|
||||
Most of them are convenience functions that basically act on some default object
|
||||
or provide function-like alternatives for the methods.
|
||||
</p>
|
||||
<h2-index/>
|
||||
<a name="angle"/><h2>"angle" - In universal DRC context: selects edges based on their orientation</h2>
|
||||
<keyword name="angle"/>
|
||||
|
|
@ -828,7 +833,7 @@ The following example selects all shapes which are rectangles and
|
|||
whose area is larger than 0.5 square micrometers:
|
||||
</p><p>
|
||||
<pre>
|
||||
out = in.drc(if_all(area > 0.5, rectangle))
|
||||
out = in.drc(if_all(area > 0.5, rectangles))
|
||||
</pre>
|
||||
</p><p>
|
||||
The condition expressions may be of any type (edges, edge pairs and polygons).
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
<title>DRC Reference: Layer Object</title>
|
||||
<keyword name="Layer"/>
|
||||
<p>
|
||||
The layer object represents a collection of polygons, edges or edge pairs.
|
||||
</p>
|
||||
<h2-index/>
|
||||
<a name="&"/><h2>"&" - Boolean AND operation</h2>
|
||||
<keyword name="&"/>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE language SYSTEM "klayout_doc.dtd">
|
||||
|
||||
<!-- generated by /home/matthias/klayout/master/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- generated by /home/matthias/klayout/0.28/scripts/drc_lvs_doc/extract_doc.rb -->
|
||||
<!-- DO NOT EDIT! -->
|
||||
|
||||
<doc>
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ module DRC
|
|||
# whose area is larger than 0.5 square micrometers:
|
||||
#
|
||||
# @code
|
||||
# out = in.drc(if_all(area > 0.5, rectangle))
|
||||
# out = in.drc(if_all(area > 0.5, rectangles))
|
||||
# @/code
|
||||
#
|
||||
# The condition expressions may be of any type (edges, edge pairs and polygons).
|
||||
|
|
|
|||
|
|
@ -105,15 +105,22 @@ MouseTracker::mouse_move_event (const db::DPoint &p, unsigned int /*buttons*/, b
|
|||
|
||||
double max_coord = 1e30; // big enough I guess
|
||||
|
||||
mp_markers.push_back (new lay::DMarker (mp_view));
|
||||
mp_markers.back ()->set_line_style (m_cursor_line_style);
|
||||
mp_markers.back ()->set_color (m_cursor_color);
|
||||
mp_markers.back ()->set (db::DEdge (db::DPoint (tp.x (), -max_coord), db::DPoint (tp.x (), max_coord)));
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
|
||||
mp_markers.push_back (new lay::DMarker (mp_view));
|
||||
mp_markers.back ()->set_line_style (m_cursor_line_style);
|
||||
mp_markers.back ()->set_color (m_cursor_color);
|
||||
mp_markers.back ()->set (db::DEdge (db::DPoint (-max_coord, tp.y ()), db::DPoint (max_coord, tp.y ())));
|
||||
mp_markers.push_back (new lay::DMarker (mp_view));
|
||||
mp_markers.back ()->set_line_style (m_cursor_line_style);
|
||||
mp_markers.back ()->set_line_width (1);
|
||||
mp_markers.back ()->set_halo (false);
|
||||
mp_markers.back ()->set_dither_pattern (1);
|
||||
mp_markers.back ()->set_color (m_cursor_color.is_valid () ? m_cursor_color : mp_view->canvas ()->foreground_color ());
|
||||
|
||||
if (i == 0) {
|
||||
mp_markers.back ()->set (db::DEdge (db::DPoint (tp.x (), -max_coord), db::DPoint (tp.x (), max_coord)));
|
||||
} else {
|
||||
mp_markers.back ()->set (db::DEdge (db::DPoint (-max_coord, tp.y ()), db::DPoint (max_coord, tp.y ())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -305,10 +305,7 @@ MoveService::handle_click (const db::DPoint &p, unsigned int buttons, bool drag_
|
|||
|
||||
if (mp_editables->begin_move (p, ac_from_buttons (buttons))) {
|
||||
|
||||
lay::SelectionService *selector = mp_view->selection_service ();
|
||||
if (selector) {
|
||||
selector->hover_reset ();
|
||||
}
|
||||
ui ()->hover_reset ();
|
||||
|
||||
mp_view->clear_transient_selection ();
|
||||
|
||||
|
|
|
|||
|
|
@ -69,14 +69,7 @@ public:
|
|||
virtual bool mouse_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
virtual bool mouse_double_click_event (const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
virtual bool wheel_event (int delta, bool horizontal, const db::DPoint &p, unsigned int buttons, bool prio);
|
||||
|
||||
/**
|
||||
* @brief Reset the hover timer for the transient selection
|
||||
*
|
||||
* This method may be used by other services (in particular Move) to avoid the transient to
|
||||
* be triggered from a move operation.
|
||||
*/
|
||||
void hover_reset ();
|
||||
virtual void hover_reset ();
|
||||
|
||||
#if defined (HAVE_QT)
|
||||
public slots:
|
||||
|
|
|
|||
|
|
@ -1051,7 +1051,15 @@ ViewObjectUI::drag_cancel ()
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
void
|
||||
ViewObjectUI::hover_reset ()
|
||||
{
|
||||
for (service_iterator svc = begin_services (); svc != end_services (); ++svc) {
|
||||
(*svc)->hover_reset ();
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
struct z_order_compare_f
|
||||
{
|
||||
|
|
|
|||
|
|
@ -147,6 +147,17 @@ public:
|
|||
virtual bool drop_event (const db::DPoint & /*p*/, const DragDropDataBase * /*data*/) { return false; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Hover reset request
|
||||
*
|
||||
* This event is issued for services providing some "hover" mode - i.e. capture
|
||||
* mouse move events and start a timer on them.
|
||||
*
|
||||
* The implementation of this event should cancel this timer and
|
||||
* not raise a hover condition.
|
||||
*/
|
||||
virtual void hover_reset () { }
|
||||
|
||||
/**
|
||||
* @brief Mouse press event handler
|
||||
*
|
||||
|
|
@ -605,6 +616,11 @@ public:
|
|||
*/
|
||||
void drag_cancel ();
|
||||
|
||||
/**
|
||||
* @brief Calls hover_reset on all services
|
||||
*/
|
||||
void hover_reset ();
|
||||
|
||||
/**
|
||||
* @brief CanvasPlane rendering
|
||||
*
|
||||
|
|
|
|||
|
|
@ -55,9 +55,6 @@
|
|||
</property>
|
||||
<item row="1" column="1">
|
||||
<widget class="lay::ColorButton" name="color_pb">
|
||||
<property name="toolTip">
|
||||
<string>The color in which the rulers are drawn</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
|
@ -151,9 +148,6 @@
|
|||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="lay::ColorButton" name="color_chc">
|
||||
<property name="toolTip">
|
||||
<string>The color in which the rulers are drawn</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
|
|
|
|||
|
|
@ -972,17 +972,31 @@ SimpleColorButton::set_color_internal (QColor c)
|
|||
m_color = c;
|
||||
|
||||
QFontMetrics fm (font (), this);
|
||||
QRect rt (fm.boundingRect (QObject::tr ("Auto"))); // dummy text to be compliant with the other color button
|
||||
QPixmap pxmp (rt.width () + 24, rt.height ());
|
||||
QRect rt (fm.boundingRect (QObject::tr ("XXXXXXX")));
|
||||
|
||||
#if QT_VERSION >= 0x050000
|
||||
double dpr = devicePixelRatio ();
|
||||
#else
|
||||
double dpr = 1.0;
|
||||
#endif
|
||||
|
||||
QPixmap pxmp (rt.width () * dpr, rt.height () * dpr);
|
||||
#if QT_VERSION >= 0x050000
|
||||
pxmp.setDevicePixelRatio (dpr);
|
||||
#endif
|
||||
|
||||
QPainter pxpainter (&pxmp);
|
||||
QColor text_color = palette ().color (QPalette::Active, QPalette::Text);
|
||||
pxpainter.setPen (QPen (text_color));
|
||||
pxpainter.setBrush (QBrush (c.isValid () ? c : QColor (128, 128, 128)));
|
||||
QRect r (0, 0, pxmp.width () - 1, pxmp.height () - 1);
|
||||
QPen frame_pen (text_color);
|
||||
frame_pen.setWidthF (1.0);
|
||||
frame_pen.setJoinStyle (Qt::MiterJoin);
|
||||
pxpainter.setPen (frame_pen);
|
||||
int dpri = int (dpr);
|
||||
QRectF r ((dpri / 2) / dpr, (dpri / 2) / dpr, rt.width () - 1.0, rt.height () - 1.0);
|
||||
pxpainter.drawRect (r);
|
||||
|
||||
setIconSize (pxmp.size ());
|
||||
setIconSize (QSize (rt.width (), rt.height ()));
|
||||
setIcon (QIcon (pxmp));
|
||||
}
|
||||
|
||||
|
|
@ -1216,22 +1230,25 @@ ColorButton::set_color_internal (QColor c)
|
|||
#if QT_VERSION >= 0x50000
|
||||
pixmap.setDevicePixelRatio (dpr);
|
||||
#endif
|
||||
pixmap.fill (QColor (0, 0, 0, 0));
|
||||
|
||||
QColor text_color = palette ().color (QPalette::Active, QPalette::Text);
|
||||
QPainter pxpainter (&pixmap);
|
||||
pxpainter.setPen (QPen (text_color));
|
||||
QPen frame_pen (text_color);
|
||||
frame_pen.setWidthF (1.0);
|
||||
frame_pen.setJoinStyle (Qt::MiterJoin);
|
||||
pxpainter.setPen (frame_pen);
|
||||
|
||||
int dpri = int (dpr);
|
||||
QRectF r ((dpri / 2) / dpr, (dpri / 2) / dpr, rt.width () - 1.0, rt.height () - 1.0);
|
||||
|
||||
if (! m_color.isValid ()) {
|
||||
|
||||
pxpainter.setFont (font ());
|
||||
QRectF r (0, 0, rt.width () - pxpainter.pen ().widthF (), rt.height () - pxpainter.pen ().widthF ());
|
||||
pxpainter.drawText (r, Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextSingleLine, QObject::tr ("Auto"));
|
||||
|
||||
} else {
|
||||
|
||||
pxpainter.setBrush (QBrush (c));
|
||||
QRectF r (0, 0, rt.width () - pxpainter.pen ().widthF (), rt.height () - pxpainter.pen ().widthF ());
|
||||
pxpainter.drawRect (r);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -602,3 +602,21 @@ TEST(Bug_1474)
|
|||
EXPECT_EQ (ex.msg (), "Cell named ADDHX2 with ID 4 was already given name SEDFFTRX2 (position=763169, cell=)");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(DuplicateCellname)
|
||||
{
|
||||
db::Manager m (false);
|
||||
db::Layout layout (&m);
|
||||
|
||||
try {
|
||||
tl::InputStream file (tl::testdata () + "/oasis/duplicate_cellname.oas");
|
||||
db::OASISReader reader (file);
|
||||
reader.read (layout);
|
||||
EXPECT_EQ (false, true);
|
||||
} catch (tl::CancelException &ex) {
|
||||
// Seen when private test data is not installed
|
||||
throw;
|
||||
} catch (tl::Exception &ex) {
|
||||
EXPECT_EQ (ex.msg (), "Same cell name TOP, but different IDs: 3 and 0 (position=1070, cell=)");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -7204,12 +7204,12 @@ class Macro:
|
|||
@overload
|
||||
def __eq__(self, other: object) -> bool:
|
||||
r"""
|
||||
@brief Compares an enum with an integer value
|
||||
@brief Compares two enums
|
||||
"""
|
||||
@overload
|
||||
def __eq__(self, other: object) -> bool:
|
||||
r"""
|
||||
@brief Compares two enums
|
||||
@brief Compares an enum with an integer value
|
||||
"""
|
||||
@overload
|
||||
def __init__(self, i: int) -> None:
|
||||
|
|
@ -7234,12 +7234,12 @@ class Macro:
|
|||
@overload
|
||||
def __ne__(self, other: object) -> bool:
|
||||
r"""
|
||||
@brief Compares an enum with an integer for inequality
|
||||
@brief Compares two enums for inequality
|
||||
"""
|
||||
@overload
|
||||
def __ne__(self, other: object) -> bool:
|
||||
r"""
|
||||
@brief Compares two enums for inequality
|
||||
@brief Compares an enum with an integer for inequality
|
||||
"""
|
||||
def __repr__(self) -> str:
|
||||
r"""
|
||||
|
|
@ -7331,12 +7331,12 @@ class Macro:
|
|||
@overload
|
||||
def __ne__(self, other: object) -> bool:
|
||||
r"""
|
||||
@brief Compares an enum with an integer for inequality
|
||||
@brief Compares two enums for inequality
|
||||
"""
|
||||
@overload
|
||||
def __ne__(self, other: object) -> bool:
|
||||
r"""
|
||||
@brief Compares two enums for inequality
|
||||
@brief Compares an enum with an integer for inequality
|
||||
"""
|
||||
def __repr__(self) -> str:
|
||||
r"""
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -1226,6 +1226,36 @@ class DBRegion_TestClass < TestBase
|
|||
|
||||
end
|
||||
|
||||
# rasterize
|
||||
def test_rasterize
|
||||
|
||||
r = RBA::Region::new()
|
||||
r.insert(RBA::Polygon::new([[0, 0], [100, 100], [150, 0]]))
|
||||
r.insert(RBA::Polygon::new(RBA::Box::new([0, 200], [100, 300])))
|
||||
|
||||
pd = RBA::Vector::new(50, 50)
|
||||
ps = RBA::Vector::new(25, 25)
|
||||
|
||||
sum = 0
|
||||
2.times do |ix|
|
||||
2.times do |iy|
|
||||
am = r.rasterize(RBA::Point::new(-50 + ix * ps.x, -20 + iy * ps.y), pd, ps, 7, 7)
|
||||
sum += am.collect { |r| r.inject(:+) }.inject(:+)
|
||||
end
|
||||
end
|
||||
|
||||
assert_equal("%.12g" % sum, "%.12g" % (7.0 * pd.x * pd.y))
|
||||
|
||||
tot = 0.0
|
||||
pd = RBA::Vector::new(50, 50)
|
||||
|
||||
am = r.rasterize(RBA::Point::new(-50, -20), pd, 7, 7)
|
||||
sum = am.collect { |r| r.inject(:+) }.inject(:+)
|
||||
|
||||
assert_equal("%.12g" % sum, "%.12g" % (7.0 * pd.x * pd.y))
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
load("test_epilogue.rb")
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
# This script is sourced to define the main version parameters
|
||||
|
||||
# The main version
|
||||
KLAYOUT_VERSION="0.28.15"
|
||||
KLAYOUT_VERSION="0.28.17"
|
||||
|
||||
# The version used for PyPI (don't use variables here!)
|
||||
KLAYOUT_PYPI_VERSION="0.28.15"
|
||||
KLAYOUT_PYPI_VERSION="0.28.17"
|
||||
|
||||
# The build date
|
||||
KLAYOUT_VERSION_DATE=$(date "+%Y-%m-%d")
|
||||
|
|
|
|||
Loading…
Reference in New Issue