191 Commits

Author SHA1 Message Date
41b6066b76 Merge branch 'dev' into japanese-translations 2021-10-02 15:09:11 +02:00
4eebff04a4 Update README.MD
Add github status badge for CI
2021-10-01 23:46:32 +02:00
04525611fa Update cmake.yml
Add gettext to dependencies
2021-10-01 23:43:37 +02:00
cb92d64ec3 Update cmake.yml 2021-10-01 23:41:40 +02:00
37ff2080f9 Create cmake.yml 2021-10-01 23:35:16 +02:00
e1b85d1a99 Merge branch 'issue/39-fix-search' of mhu/gds-render into dev 2020-11-26 23:08:55 +01:00
b0c9afdae5 Fix #39: Checking of pure library entry in cell selector was broken 2020-11-26 23:07:48 +01:00
f6abfada2c ColorPalette: Fix Dispose function
* Set freed pointer to NULL in dispose function because dispose cna be run multiple times. This fixes the case of freeing an already freed pointer.
2020-07-09 23:54:40 +02:00
f135b42d8a make clear we're not getting a return value from vector_2d_copy 2020-06-29 20:03:38 +02:00
058564326b Update library and compiler versions in doxygen 2020-04-24 01:17:20 +02:00
3546c9a7f9 Merge branch 'dev' into japanese-translations 2020-04-24 01:09:26 +02:00
fd1eac7fda Merge branch 'master' into dev 2020-04-24 01:07:50 +02:00
2c91956b32 Doxygen: Update calculate_cell_bounding_box()
* Fix typo
* Extend description
2020-04-24 01:05:37 +02:00
232d025211 Doxygen: Update calculate_cell_bounding_box()
* Add note about problematic behaviour
* Fix typos
2020-04-24 01:02:10 +02:00
ceeb67355d Fix #38: Make parser store the datatype record of a graphics object 2020-04-19 02:58:34 +02:00
ba51a437a4 Fix definition of datatype in GDS graphics type 2020-04-19 02:57:15 +02:00
e461b0be1d Merge branch 'dev' 2020-04-19 00:52:42 +02:00
42f1636860 Make unit test reporting compact 2020-04-19 00:50:30 +02:00
d29109e516 Add unittests for calculation functions for vectors 2020-04-19 00:40:17 +02:00
b784f28d4c Change unit test output to include successful tests as well 2020-04-19 00:40:03 +02:00
94851570e9 Add preliminary working principle of unit tests 2020-04-18 03:23:15 +02:00
f4fa1bd4e5 Make tests link against libraries 2020-04-18 02:45:23 +02:00
2e7bb03c17 Add testing folder to doxygen's exclude list 2020-04-18 02:38:40 +02:00
39ff0dec1a Add test target to cmake 2020-04-18 02:32:11 +02:00
74f9663bde Add catch framework for testing 2020-04-18 02:21:23 +02:00
8f54f92ac0 Merge branch 'dev' into japanese-translations 2020-04-16 22:47:55 +02:00
330285cc2f Merge branch 'master' into dev 2020-04-16 22:47:38 +02:00
24ae5e4d5b Fix #37: Introduce new versioning scheme for AUR PKGBUILD 2020-04-16 22:43:29 +02:00
f7d15c7267 Fix comment style from // to /**/ 2020-04-07 15:39:38 +02:00
00d02b8291 Issue #36: Fix possible memory leak of async status message, if rendering finishes, before message could be displayed 2020-04-03 20:53:32 +02:00
75e01b80c8 Issue #36: Fix memory leaks in set-property function of lib-cell-renderer 2020-04-03 20:32:05 +02:00
89f9a638c6 Add license header to file 2020-04-02 00:47:43 +02:00
cba28b378e Merge branch 'master' into japanese-translations 2020-01-16 23:39:11 +01:00
7b1722661c Fix typo in documentation 2020-01-16 23:38:20 +01:00
29212b0a92 Translations: Add shitty Japanese translations. Not yet completed 2020-01-16 22:55:05 +01:00
5a43a8a4bf Rename functions of bounding box to be more consistent 2020-01-14 19:03:26 +01:00
f11e11e6a7 Doxygen: Add brief description for conv_generic_to_vector_2d_t 2020-01-14 19:02:50 +01:00
0c5dd3c8e7 Doxygen: Document union bounding_box 2020-01-14 18:52:03 +01:00
77a3a0da5a Doxygen: Fix typo 2020-01-14 18:52:03 +01:00
f8b0b63937 Doxygen: Remove warning from uncommented code printf and place it in doxygen @warning tag instead 2020-01-14 18:51:55 +01:00
2d389342fd cairo-renderer: Update coding style and add comment explaining how to use the inter process communication to update the GUI with rendering status updates 2020-01-14 14:09:24 +01:00
5f21f8c146 Switch to 3 digit versioning 2019-12-20 21:48:23 +01:00
c4baffe49d Add Add Japanese translation PO. Ready for translation. 2019-12-16 22:40:57 +01:00
5f94ec49bf Merge branch 'dev' into japanese-translations 2019-12-16 22:38:48 +01:00
1ca04aaa71 Doxygen: Update image of Gui and its description. Fix #31 2019-12-16 22:09:14 +01:00
b8fc904af5 Fix typos 2019-12-16 22:00:59 +01:00
fdfa478fed Add full German translation 2019-12-16 21:58:18 +01:00
c0182220f1 Translations: Generate only one PO template file for all input files. Include glade files into translation, delete previous German Translation 2019-12-16 18:29:28 +01:00
798262383e Update the POT files 2019-12-12 21:39:08 +01:00
0bfe8df92f Update POT files 2019-12-12 21:24:19 +01:00
de9066f181 Add translation markers to all messages except for the gds parser's messages 2019-12-12 21:22:14 +01:00
87bc60bed0 Fix style issue in version.c 2019-12-12 20:36:17 +01:00
20d72a5edb Remove outdated TODO from source file 2019-12-12 20:34:41 +01:00
9e8d0b4611 include/gds-utils/gds-types.h: Fix typo in comment 2019-12-11 08:25:24 +01:00
4550815901 Fix code style 2019-12-07 19:07:52 +01:00
e3b6ee66ef Fix typo in comment 2019-11-28 17:59:06 +01:00
f3786cf282 Gui: Add library name to all cells in cell selector 2019-11-25 20:48:09 +01:00
c085a62036 GUI: Remove access and modification date from cell selector
Fix #28
2019-11-25 20:45:57 +01:00
55799b2266 Merge branch 'master' into dev 2019-11-19 01:33:56 +01:00
4970585cee Remove call to g_task_set(). It is not available under debian 2019-11-19 01:33:44 +01:00
c6483dbebd Merge branch 'master' into dev 2019-11-18 22:30:51 +01:00
86342da2a2 Remove unneeded comments 2019-11-18 22:30:05 +01:00
ce8386799b external renderer: Rename FUNC_DECL to EXPORTED_FUNC_DECL to show that it also exports a function 2019-11-18 21:59:42 +01:00
374e3b54c0 plugins: example plugin: Make all functions invisible except for the explicitly exported ones
* Add target parameters to compile all symbols invisible to the outside by default.
* Edit FUNC_DECL() macro to set attribute that exports the function
2019-11-18 21:56:22 +01:00
3651296c3a Merge branch 'master' into dev 2019-11-17 22:31:47 +01:00
5fe21f1d73 bounding box: Fix doxygen documentation typo 2019-11-17 22:31:31 +01:00
2d7103abbb Fix doxygen 2019-11-17 14:49:00 +01:00
392d7e1b3c plugins: Add license header and doxygen file 2019-11-17 14:09:53 +01:00
2fddfa475b Merge branch 'master' into dev 2019-11-17 01:52:05 +01:00
e6603d4c13 Fix broken latex generation 2019-11-16 16:16:01 +01:00
80730ab9c4 Merge branch 'master' into dev 2019-11-16 16:02:51 +01:00
2b0e2095e6 Update documentation and implementations of bounding box calculations. Rename functions to fit their behavior 2019-11-16 16:02:33 +01:00
0c20db39bd Update documentation and implementations of bounding box calculations. Rename functions to fit their behavior 2019-11-16 15:54:56 +01:00
1b1f742ae1 Fix doxygen for command line header 2019-11-15 21:39:33 +01:00
3b6837b886 Rename python renderer to plugin example and leave it be as a template 2019-11-15 21:34:13 +01:00
efb1af7ee0 Complete chain of passing command line parameters to external renderer 2019-11-15 21:11:41 +01:00
fa1a78e54c Edit comments 2019-11-15 21:06:41 +01:00
0417784877 Add property for command line parameters to external renderer 2019-11-15 21:04:59 +01:00
c186d3cdb3 Pass command line parameters for shared object renderer to command line convert struct 2019-11-15 20:50:46 +01:00
f02a720f99 Uodate translations of main.c 2019-11-15 20:35:36 +01:00
374a893dda Add W option to command line parser for external renderer parameters 2019-11-15 20:31:57 +01:00
83a7848c14 Merge branch 'dev' into external-renderer-rework 2019-11-14 23:39:40 +01:00
7977ee7c8b Merge branch 'master' into dev 2019-11-14 23:39:29 +01:00
e7f0f904e8 main: Free command line option context, add comment for freeing all the command line parameter data 2019-11-14 23:39:12 +01:00
48eb2c296f Merge branch 'dev' into external-renderer-rework 2019-11-14 19:36:59 +01:00
3d5c4daad9 Doxygen: Rework documentation make targets
* new target doxygen-pdf which build the latex output
* Add doxygen-pdf to documentation target
* Move documentaiton target definition to doxygen's CMakeLists.txt
2019-11-14 19:32:54 +01:00
9899b94db6 cmake: rework source list for generated files 2019-11-14 19:31:57 +01:00
f153485996 Implement base construct of new external renderer. CLI parameters still not implemented. Currently NULL is passed to init func. Forking implemented but not tested 2019-11-12 21:15:36 +01:00
f15e82b5dc Modify External Renderer: External renderer docu updated for future changes, restructuring. Not that the changes in the documentation are not yet implemented in code 2019-11-12 20:52:42 +01:00
c497a41ca6 Merge branch 'dev' into japanese-translations 2019-11-12 19:58:03 +01:00
daf12a7d8c Merge branch 'dev' into python-renderer 2019-11-12 19:55:01 +01:00
11f2068b76 Improve Cmake target for translations. Still not perfect. 2019-11-12 19:53:16 +01:00
24d66e74fe Merge commit '866d36873a4adef0ef8505de25740c03ec92a2e0' into dev 2019-11-12 19:53:02 +01:00
58a0bd85c4 Improve Cmake target for translations. Still not perfect. 2019-11-12 19:50:34 +01:00
f8de3468de Merge branch 'translations' into python-renderer 2019-11-12 19:16:12 +01:00
4cc31c81e3 Move plugins in CMakeLists.txt so they don't need to fullfil all warnign restrictions of the main application 2019-11-12 19:14:58 +01:00
74dfbd9b34 Add preliminary construct for plugin renderers (shared object renderers) 2019-11-12 19:12:57 +01:00
40a7e5a650 Compilation: Add -Wextra to compile arguments + Fix minor resulting warnings 2019-11-12 18:14:07 +01:00
d8f6981fe6 Gui: Only promt overwrite message of auto-naming tool when there are actual elements in the layer selector 2019-11-09 02:21:57 +01:00
4e38d8f452 LayerSelector: Add layer_selector_contains_elements() function 2019-11-09 02:18:53 +01:00
25efe527c3 Merge branch 'translations' into japanese-translations 2019-11-09 01:52:18 +01:00
866d36873a Merge branch 'dev' into translations 2019-11-09 01:52:00 +01:00
74eb17b2dc Merge branch 'dev' 2019-11-09 01:50:37 +01:00
0304c0d08b Adapt Header bar to show title correctly 2019-11-03 21:07:56 +01:00
70ea6a8901 Merge branch 'master' into translations 2019-10-29 00:03:30 +01:00
529b49ee2e Fix coding style problems in bounding-box.c 2019-10-28 23:57:54 +01:00
6d31193123 Fix coding style in vector-operations.c 2019-10-28 23:55:22 +01:00
e7bf59aa8c Merge branch 'master' into translations 2019-10-28 22:44:06 +01:00
188c6f5d87 Fix style of gds-tree-checker 2019-10-28 22:43:28 +01:00
92e40cb8ca Fix PKGBuild 2019-10-28 21:50:03 +01:00
8f788e262f Merge branch 'dev' into translations 2019-10-25 21:20:16 +02:00
2e8e258b49 Style improvements 2019-10-25 21:16:31 +02:00
547b002e57 style fixes in layer-element.c 2019-10-25 20:54:11 +02:00
c7ce62673f Style fixes in conv settings dialog 2019-10-25 20:52:22 +02:00
dd488c3105 Further style mprovements 2019-10-25 20:45:25 +02:00
be0d58c54e Fix coding style in main.c 2019-10-25 20:36:54 +02:00
0507fa673b Merge branch 'translations' into japanese-translations 2019-10-25 20:30:25 +02:00
4a6b0dc879 Update translation for German 2019-10-25 20:30:08 +02:00
3d55b0ccec Start Japanese translations 2019-10-25 20:24:50 +02:00
f7b2a331ec Add German translations for command line interface 2019-10-22 23:13:09 +02:00
e90cd1313d remove useless tab at end of line in script 2019-10-22 22:59:05 +02:00
0fbbc1db64 Update package build 2019-10-20 14:26:46 +02:00
8005e8bcc7 Adapt install routines to install locales 2019-10-20 14:04:39 +02:00
31a47339f8 Update translations 2019-10-18 23:25:27 +02:00
7753e42078 Add translation output to Cmake 2019-10-18 22:51:31 +02:00
b2ffc709bb Started first translation approach 2019-10-18 21:19:38 +02:00
b6c6262662 Add helper scripts for gettext 2019-10-18 20:34:03 +02:00
c70f99a283 Remove uneeded empty line in CMakeLists.txt 2019-10-18 20:32:58 +02:00
592dcbae53 Use translations folder in binary dir when debugging 2019-10-18 19:39:54 +02:00
f1102162b7 Add dirty warning to version Cmake 2019-10-18 19:39:23 +02:00
8bef6bcb17 First inits for translations 2019-10-18 19:29:55 +02:00
dc40dec212 Add colors to cmake output 2019-10-18 19:29:04 +02:00
56591fb675 Merge branch 'dev' of git.shimatta.de:mhu/gds-render into dev 2019-10-18 18:13:05 +02:00
7fdd1f6c92 Add tooltips to main window's buttons 2019-10-18 18:12:21 +02:00
1f914d1218 Add version dependent application id. Multiple versions of htis program can now run at the same time 2019-10-03 11:57:53 +02:00
13e202424b Text improvements 2019-10-03 11:57:16 +02:00
a48fe9ab58 Merge branch 'master' into dev 2019-09-28 23:29:22 +02:00
9bd225b837 Merge branch 'Issue-28-new-gui-features' into dev 2019-09-28 23:20:14 +02:00
00d6710922 Doxygen error fixes 2019-09-28 23:16:48 +02:00
67b8dc2443 Doxygen fix 2019-09-28 23:16:48 +02:00
6eaf86dc1c Fix doxygen configuartion to handle __attribute__ correctly 2019-09-28 23:16:48 +02:00
1de96f501c Checked renderers for memory leaks 2019-09-28 23:16:48 +02:00
01e61a79fd Integrate cell selector to main gui class 2019-09-28 23:16:48 +02:00
dc30950df5 Tree store for cell selection moved to GUI file 2019-09-28 23:16:48 +02:00
23775b079a Code improvements 2019-09-28 23:16:48 +02:00
a65295fbeb remove now unneeded mapping parser completely 2019-09-28 23:16:48 +02:00
9245d68da1 LayerSelector: Use Layer Settings for CSV export. This makes the mapping parser unnecessary. It can be removed 2019-09-28 23:16:48 +02:00
0a04f2fed4 LayerSettings: Fix bug in CSV export function 2019-09-28 23:16:48 +02:00
62388e4053 Remove code from mapping parser that implements csv read. Use LayerSettings class instead. 2019-09-28 23:16:48 +02:00
c365c89908 LayerSelector: Make import of layer information from CSV independed from mapping-parser code. Use LayerSettings class instead. 2019-09-28 23:16:48 +02:00
f20826ccf7 LayerSettings: Fix layer_settings_load_from_csv()
* Add stacked position to layer settings
* Check if layer_settings instance is valid
2019-09-28 23:16:48 +02:00
94ef879a94 Refactoring: rename progress update func of output renderer to gds_output_renderer_update_async_progress() 2019-09-28 23:16:48 +02:00
977547d91d Enable status upgrades from Cairo renderer to activity bar. 2019-09-28 23:16:48 +02:00
0dc91c14de Add project entry to libversion CMAKE 2019-09-28 23:16:48 +02:00
5ec7832ac4 Cairo Renderer: Add function that reads a line from a file descriptor (pipe) 2019-09-28 23:16:48 +02:00
52fb07bea6 Add warning for fallthrough to switch-case 2019-09-28 23:16:48 +02:00
eefe0df984 Remove warning about wrong bounding box calculation. Still wrong but the warning is annoying and problems are negligible. 2019-09-28 23:16:48 +02:00
e3e39a80ee Move compiler flags up in CMAKE, so they apply also for included subprojects 2019-09-28 23:16:48 +02:00
448de30b91 Doxygen fix 2019-09-28 23:01:12 +02:00
ec9a65cec5 Fix doxygen configuartion to handle __attribute__ correctly 2019-09-28 22:59:51 +02:00
7cbde0f30a Fixup round for doxygen 2019-09-28 22:57:31 +02:00
00d7691bda Code improvements 2019-09-28 20:46:41 +02:00
b8a02912b0 Merge branch 'master' into Issue-28-new-gui-features 2019-09-25 19:14:42 +02:00
e703d4427a Update image of GUI in documentation 2019-09-25 19:14:06 +02:00
f9e16fa4d7 Merge branch 'dev' into Issue-28-new-gui-features 2019-09-25 18:54:21 +02:00
1bf01a5cd2 Merge branch 'master' into dev 2019-09-25 18:50:03 +02:00
cd3ef452f1 Merge branch 'master' into Issue-28-new-gui-features 2019-09-25 18:49:38 +02:00
40edd21f0a Fix typo in application description 2019-09-25 18:47:28 +02:00
bcc8623382 remove now unneeded mapping parser completely 2019-09-25 18:25:12 +02:00
a9ccf6533d LayerSelector: Use Layer Settings for CSV export. This makes the mapping parser unnecessary. It can be removed 2019-09-25 18:21:02 +02:00
e16b7f9d25 LayerSettings: Fix bug in CSV export function 2019-09-25 18:20:03 +02:00
16b18fc5b3 Remove code from mapping parser that implements csv read. Use LayerSettings class instead. 2019-09-25 17:59:38 +02:00
941711129a LayerSelector: Make import of layer information from CSV independed from mapping-parser code. Use LayerSettings class instead. 2019-09-25 17:58:32 +02:00
d90c1b389e LayerSettings: Fix layer_settings_load_from_csv()
* Add stacked position to layer settings
* Check if layer_settings instance is valid
2019-09-25 17:54:26 +02:00
291ded0277 Refactoring: rename progress update func of output renderer to gds_output_renderer_update_async_progress() 2019-09-19 21:44:30 +02:00
5f6dbbed0e Enable status upgrades from Cairo renderer to activity bar. 2019-09-19 21:42:55 +02:00
8b1d3709b7 Add project entry to libversion CMAKE 2019-09-18 20:40:16 +02:00
4db8593e5b Cairo Renderer: Add function that reads a line from a file descriptor (pipe) 2019-09-18 20:39:42 +02:00
bea35bf952 Add warning for fallthrough to switch-case 2019-09-18 20:38:32 +02:00
ad5e0ebe11 Remove warning about wrong bounding box calculation. Still wrong but the warning is annoying and problems are negligible. 2019-09-18 20:37:51 +02:00
ee99e50656 Move compiler flags up in CMAKE, so they apply also for included subprojects 2019-09-18 20:36:50 +02:00
c016a5e96e Revert "Add benchmark for GDS-rendering. Will be removed later"
This reverts commit bd97ccf44f.
2019-09-15 13:28:40 +02:00
cfc156c1c0 Improve performance by prepending to list inststead of appending. O(n^2) -> O(1) 2019-09-15 13:28:05 +02:00
bd97ccf44f Add benchmark for GDS-rendering. Will be removed later 2019-09-15 13:11:38 +02:00
df7cc6d0fc Fix typo in name of function 2019-09-15 13:04:30 +02:00
8be5bd230b Fix #26: Implement callback function for auto naming button 2019-08-29 18:31:53 +02:00
3a72796b2f Fix docu for layer_selector_auto_color_layers 2019-08-29 18:20:19 +02:00
9f7e1e1696 Issue #26: Add layer_selector_auto_name_layers() function 2019-08-29 18:19:28 +02:00
27f5a5e3d2 Issue #26: Setup callback for auto naming button 2019-08-29 17:58:39 +02:00
ec72fb2aa1 Issue #26: Add auto naming button to gui 2019-08-29 17:52:49 +02:00
4968492eee Fix unnecessary space in string after newline 2019-08-29 17:49:23 +02:00
66 changed files with 20736 additions and 966 deletions

37
.github/workflows/cmake.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: CMake
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
jobs:
build:
# The CMake configure and build commands are platform agnostic and should work equally
# well on Windows or Mac. You can convert this to a matrix build if you need
# cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install system dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get -y install libgtk-3-dev gettext
- name: Configure CMake
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
- name: Build
# Build your program with the given configuration
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}

View File

@@ -1,7 +1,7 @@
# Maintainer: Mario Hüttel <mario (dot) huettel (!) gmx (dot) net>
# Maintainer: Mario Hüttel <mario (dot) huettel (!) gmx (dot) net>
pkgname=gds-render
pkgver=20180725.001
pkgver=v1.2_10_g00d02b8
pkgrel=1
pkgdesc="Conversion tool for converting GDS layout files into TikZ Code and PDF"
arch=('i686' 'x86_64')
@@ -15,18 +15,19 @@ sha1sums=('SKIP')
pkgver () {
_date=`date +"%Y%m%d"`
cd "${srcdir}/${pkgname}-git"
echo "$_date.$(git rev-list --count master).$(git rev-parse --short master)"
cd "${srcdir}/${pkgname}-git/version"
echo "$(echo "$(sh ./generate-version-string.sh)" | sed 's/-/_/g')"
}
build () {
cd "$srcdir/$pkgname-git"
cmake -DCMAKE_BUILD_TYPE=Release .
mkdir "$srcdir/$pkgname-git/build"
cd "$srcdir/$pkgname-git/build"
cmake -DCMAKE_BUILD_TYPE=Release ..
make
}
package () {
cd "$srcdir/$pkgname-git"
cd "$srcdir/$pkgname-git/build"
make DESTDIR="${pkgdir}" install
install -D -m664 "$srcdir/$pkgname-git/AUR/gds-render.desktop" \
"$pkgdir/usr/share/applications/gds-render.desktop"
@@ -34,4 +35,6 @@ package () {
"$pkgdir/usr/share/icons/hicolor/scalable/apps/gds-render.svg"
install -D -m664 "$srcdir/$pkgname-git/icon/128x128/gds-render.png" \
"$pkgdir/usr/share/icons/hicolor/128x128/apps/gds-render.png"
(cd $srcdir/$pkgname-git/build/translations/output/ && tar cf - "locale" | (cd "$pkgdir/usr/share/" && tar xf -))
}

View File

@@ -1,18 +1,48 @@
project(gds-render)
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "/usr/" CACHE PATH "..." FORCE)
endif()
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColorReset "${Esc}[m")
set(ColorBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
cmake_minimum_required(VERSION 2.8)
find_package(PkgConfig REQUIRED)
pkg_search_module(GLIB REQUIRED glib-2.0)
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
pkg_check_modules(CAIRO REQUIRED cairo)
add_subdirectory(resources)
add_subdirectory(doxygen)
add_subdirectory(version)
include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include)
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
add_definitions(${GLIB2_CFLAGS_OTHER})
add_subdirectory(plugins)
IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("${Yellow}Debug mode for translations used!${ColorReset}")
add_definitions(-DGETTEXT_PACKAGE=\"gds-render\" -DLOCALEDATADIR=\"${CMAKE_CURRENT_BINARY_DIR}/translations/output\")
message("${BoldMagenta}${CMAKE_CURRENT_BINARY_DIR}/translations/output used as data dir${ColorReset}")
else(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("Global locale directory used. Make sure files in /usr/share/locale are available")
add_definitions(-DGETTEXT_PACKAGE=\"gds-render\" -DLOCALEDATADIR=\"/usr/share\")
ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
aux_source_directory("widgets" LAYER_SOURCES)
aux_source_directory("cell-selector" CELL_SELECTOR_SOURCES)
@@ -32,13 +62,33 @@ set(SOURCE
${LAYER_SELECTOR_SOURCES}
)
add_compile_options(-Wall -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter)
set(SOURCE_GENERATED
${CMAKE_CURRENT_BINARY_DIR}/resources/resources.c
)
add_executable(${PROJECT_NAME} ${SOURCE} ${CMAKE_CURRENT_BINARY_DIR}/resources/resources.c)
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
SET_SOURCE_FILES_PROPERTIES(${SOURCE_GENERATED} PROPERTIES GENERATED 1)
add_subdirectory(test)
add_compile_options(-Wall -Wextra -Wold-style-declaration -Wuninitialized -Wmaybe-uninitialized -Wunused-parameter)
add_subdirectory(resources)
add_subdirectory(doxygen)
add_subdirectory(translations)
add_subdirectory(version)
link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS})
add_definitions(${GLIB2_CFLAGS_OTHER})
add_executable(${PROJECT_NAME} ${SOURCE} ${SOURCE_GENERATED})
add_dependencies(${PROJECT_NAME} glib-resources)
add_dependencies(${PROJECT_NAME} version)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/resources/resources.c PROPERTIES GENERATED 1)
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS})
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
add_dependencies(${PROJECT_NAME} translations)
install (TARGETS ${PROJECT_NAME}
RUNTIME
DESTINATION bin
)
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS})
add_custom_target(documentation DEPENDS doxygen)

View File

@@ -1,5 +1,7 @@
# GDS-Render Readme
[![CMake](https://github.com/0mhu/gds-render/actions/workflows/cmake.yml/badge.svg?branch=master)](https://github.com/0mhu/gds-render/actions/workflows/cmake.yml)
This software is a rendering programm for GDS2 layout files.
The GDS2 format is mainly used in integrated circuit development.
This program allows the conversion of a GDS file to a vector graphics file.

View File

@@ -88,11 +88,13 @@ static void lib_cell_renderer_set_property(GObject *object,
g_value_init(&val, G_TYPE_STRING);
g_value_set_string(&val, ((struct gds_library *)g_value_get_pointer(value))->name);
g_object_set_property(object, "text", &val);
g_value_unset(&val);
break;
case PROP_CELL:
g_value_init(&val, G_TYPE_STRING);
g_value_set_string(&val, ((struct gds_cell *)g_value_get_pointer(value))->name);
g_object_set_property(object, "text", &val);
g_value_unset(&val);
break;
case PROP_ERROR_LEVEL:
/* Set cell color according to error level */
@@ -100,6 +102,7 @@ static void lib_cell_renderer_set_property(GObject *object,
convert_error_level_to_color(&color, g_value_get_uint(value));
g_value_set_boxed(&val, &color);
g_object_set_property(object, "foreground-rgba", &val);
g_value_unset(&val);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);

View File

@@ -1,176 +0,0 @@
/*
* GDSII-Converter
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file tree-store.h
* @brief Tree store implementation
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup GUI
* @{
*/
#include <gds-render/cell-selector/tree-store.h>
#include <gds-render/cell-selector/lib-cell-renderer.h>
#include <gds-render/gds-utils/gds-types.h>
/**
* @brief this function olny allows cells to be selected
* @param selection
* @param model
* @param path
* @param path_currently_selected
* @param data
* @return TRUE if element is selectable, FALSE if not
*/
static gboolean tree_sel_func(GtkTreeSelection *selection,
GtkTreeModel *model,
GtkTreePath *path,
gboolean path_currently_selected,
gpointer data)
{
GtkTreeIter iter;
struct gds_cell *cell;
unsigned int error_level;
gboolean ret = FALSE;
(void)selection;
(void)path_currently_selected;
(void)data;
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell, CELL_SEL_CELL_ERROR_STATE, &error_level, -1);
/* Allow only rows with _valid_ cell to be selected */
if (cell) {
/* Cell available. Check if it passed the critical checks */
if (!(error_level & LIB_CELL_RENDERER_ERROR_ERR))
ret = TRUE;
}
return ret;
}
/**
* @brief cell_store_filter_visible_func Decides whether an element of the tree model @p model is visible.
* @param model Tree model
* @param iter Current element / iter in Model to check
* @param data Data. Set to static stores variable
* @return TRUE if visible, else FALSE
* @note TODO: Maybe implement Damerau-Levenshtein distance matching
*/
static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{
struct tree_stores *stores = (struct tree_stores *)data;
struct gds_cell *cell;
struct gds_library *lib;
gboolean result = FALSE;
const char *search_string;
if (!model || !iter || !stores)
goto exit_filter;
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
if (lib) {
result = TRUE;
goto exit_filter;
}
if (!cell)
goto exit_filter;
search_string = gtk_entry_get_text(stores->search_entry);
/* Show all, if field is empty */
if (!strlen(search_string))
result = TRUE;
if (strstr(cell->name, search_string))
result = TRUE;
gtk_tree_view_expand_all(stores->base_tree_view);
exit_filter:
return result;
}
static void change_filter(GtkWidget *entry, gpointer data)
{
struct tree_stores *stores = (struct tree_stores *)data;
(void)entry;
gtk_tree_model_filter_refilter(stores->filter);
}
/**
* @brief Setup a GtkTreeView with the necessary columns
* @param view Tree view to set up
* @param search_entry Entry field for search
* @return Tree stores for storing data inside the GtkTreeView
*/
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry)
{
static struct tree_stores stores;
GtkCellRenderer *render_dates;
GtkCellRenderer *render_cell;
GtkCellRenderer *render_lib;
GtkTreeViewColumn *column;
stores.base_tree_view = view;
stores.search_entry = search_entry;
stores.base_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING);
/* Searching */
if (search_entry) {
stores.filter = GTK_TREE_MODEL_FILTER(gtk_tree_model_filter_new(GTK_TREE_MODEL(stores.base_store), NULL));
gtk_tree_model_filter_set_visible_func (stores.filter,
(GtkTreeModelFilterVisibleFunc)cell_store_filter_visible_func,
&stores, NULL);
g_signal_connect(GTK_SEARCH_ENTRY(search_entry), "search-changed", G_CALLBACK(change_filter), &stores);
}
gtk_tree_view_set_model(view, GTK_TREE_MODEL(stores.filter));
render_dates = gtk_cell_renderer_text_new();
render_cell = lib_cell_renderer_new();
render_lib = lib_cell_renderer_new();
column = gtk_tree_view_column_new_with_attributes("Library", render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
gtk_tree_view_append_column(view, column);
column = gtk_tree_view_column_new_with_attributes("Cell", render_cell, "gds-cell", CELL_SEL_CELL,
"error-level", CELL_SEL_CELL_ERROR_STATE, NULL);
gtk_tree_view_append_column(view, column);
column = gtk_tree_view_column_new_with_attributes("Mod. Date", render_dates, "text", CELL_SEL_MODDATE, NULL);
gtk_tree_view_append_column(view, column);
column = gtk_tree_view_column_new_with_attributes("Acc. Date", render_dates, "text", CELL_SEL_ACCESSDATE, NULL);
gtk_tree_view_append_column(view, column);
/* Callback for selection
* This prevents selecting a library */
gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(view), tree_sel_func, NULL, NULL);
return &stores;
}
/** @} */

View File

@@ -29,10 +29,10 @@
*/
#include <stdio.h>
#include <glib/gi18n.h>
#include <gds-render/command-line.h>
#include <gds-render/gds-utils/gds-parser.h>
#include <gds-render/layer/mapping-parser.h>
#include <gds-render/layer/layer-settings.h>
#include <gds-render/output-renderers/cairo-renderer.h>
#include <gds-render/output-renderers/latex-renderer.h>
@@ -56,7 +56,7 @@ static int create_renderers(char **renderers,
char **output_file_names,
gboolean tex_layers,
gboolean tex_standalone,
const char *so_path,
const struct external_renderer_params *ext_params,
GList **renderer_list,
LayerSettings *layer_settings)
{
@@ -71,14 +71,14 @@ static int create_renderers(char **renderers,
return -1;
if (!renderers || !output_file_names) {
fprintf(stderr, "Please specify renderers and file names\n");
fprintf(stderr, _("Please specify renderers and file names\n"));
return -1;
}
count_render = string_array_count(renderers);
count_out = string_array_count(output_file_names);
if (count_render != count_out) {
fprintf(stderr, "Count of renderers %d does not match count of output file names %d\n",
fprintf(stderr, _("Count of renderers %d does not match count of output file names %d\n"),
count_render, count_out);
return -1;
}
@@ -100,11 +100,13 @@ static int create_renderers(char **renderers,
} else if (!strcmp(current_renderer, "svg")) {
output_renderer = GDS_RENDER_OUTPUT_RENDERER(cairo_renderer_new_svg());
} else if (!strcmp(current_renderer, "ext")) {
if (!so_path) {
fprintf(stderr, "Please specify shared object for external renderer. Will ignore this renderer.\n");
if (!ext_params->so_path) {
fprintf(stderr, _("Please specify shared object for external renderer. Will ignore this renderer.\n"));
continue;
}
output_renderer = GDS_RENDER_OUTPUT_RENDERER(external_renderer_new_with_so(so_path));
output_renderer = GDS_RENDER_OUTPUT_RENDERER(
external_renderer_new_with_so_and_param(ext_params->so_path,
ext_params->cli_params));
} else {
continue;
}
@@ -138,7 +140,7 @@ int command_line_convert_gds(const char *gds_name,
char **renderers,
char **output_file_names,
const char *layer_file,
const char *so_path,
struct external_renderer_params *ext_param,
gboolean tex_standalone,
gboolean tex_layers,
double scale)
@@ -155,7 +157,7 @@ int command_line_convert_gds(const char *gds_name,
/* Check if parameters are valid */
if (!gds_name || !cell_name || !output_file_names || !layer_file || !renderers) {
printf("Probably missing argument. Check --help option\n");
printf(_("Probably missing argument. Check --help option\n"));
return -2;
}
@@ -165,7 +167,7 @@ int command_line_convert_gds(const char *gds_name,
/* Create renderers */
if (create_renderers(renderers, output_file_names, tex_layers, tex_standalone,
so_path, &renderer_list, layer_sett))
ext_param, &renderer_list, layer_sett))
goto ret_destroy_layer_mapping;
@@ -181,7 +183,7 @@ int command_line_convert_gds(const char *gds_name,
first_lib = (struct gds_library *)libs->data;
if (!first_lib) {
fprintf(stderr, "No library in library list. This should not happen.\n");
fprintf(stderr, _("No library in library list. This should not happen.\n"));
/* This is safe. Library destruction can handle an empty list element */
goto ret_destroy_library_list;
}
@@ -190,27 +192,27 @@ int command_line_convert_gds(const char *gds_name,
toplevel_cell = find_gds_cell_in_lib(first_lib, cell_name);
if (!toplevel_cell) {
printf("Couldn't find cell in first library!\n");
printf(_("Couldn't find cell in first library!\n"));
goto ret_destroy_library_list;
}
/* Check if cell passes vital checks */
res = gds_tree_check_reference_loops(toplevel_cell->parent_library);
if (res < 0) {
fprintf(stderr, "Checking library %s failed.\n", first_lib->name);
fprintf(stderr, _("Checking library %s failed.\n"), first_lib->name);
goto ret_destroy_library_list;
} else if (res > 0) {
fprintf(stderr, "%d reference loops found.\n", res);
fprintf(stderr, _("%d reference loops found.\n"), res);
/* do further checking if the specified cell and/or its subcells are affected */
if (toplevel_cell->checks.affected_by_reference_loop == 1) {
fprintf(stderr, "Cell is affected by reference loop. Abort!\n");
fprintf(stderr, _("Cell is affected by reference loop. Abort!\n"));
goto ret_destroy_library_list;
}
}
if (toplevel_cell->checks.affected_by_reference_loop == GDS_CELL_CHECK_NOT_RUN)
fprintf(stderr, "Cell was not checked. This should not happen. Please report this issue. Will continue either way.\n");
fprintf(stderr, _("Cell was not checked. This should not happen. Please report this issue. Will continue either way.\n"));
/* Note: unresolved references are not an abort condition.
* Deal with it.
@@ -225,9 +227,8 @@ int command_line_convert_gds(const char *gds_name,
ret_destroy_library_list:
clear_lib_list(&libs);
ret_clear_renderers:
for (list_iter = renderer_list; list_iter; list_iter = list_iter->next) {
for (list_iter = renderer_list; list_iter; list_iter = list_iter->next)
g_object_unref(list_iter->data);
}
ret_destroy_layer_mapping:
g_object_unref(layer_sett);
return ret;

View File

@@ -1,10 +1,19 @@
find_package(Doxygen)
if (DOXYGEN_FOUND)
add_custom_target(doxygen
add_custom_target(documentation DEPENDS doxygen doxygen-pdf)
add_custom_target(doxygen
COMMAND ./build-doxygen.sh "${PROJECT_BINARY_DIR}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating documentation with Doxygen")
add_custom_target(
doxygen-pdf
COMMAND make
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}/latex"
DEPENDS doxygen
)
else (DOXYGEN_FOUND)
message("Doxygen need to be installed to generate the doxygen documentation")
message("Doxygen needs to be installed to generate the doxygen documentation")
endif (DOXYGEN_FOUND)

View File

@@ -1,4 +1,4 @@
# Doxyfile 1.8.16
# Doxyfile 1.8.17
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -309,7 +309,7 @@ OPTIMIZE_OUTPUT_SLICE = NO
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
@@ -535,8 +535,8 @@ HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# (class|struct|union) declarations. If set to NO, these declarations will be
# included in the documentation.
# declarations. If set to NO, these declarations will be included in the
# documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
@@ -851,8 +851,10 @@ INPUT_ENCODING = UTF-8
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen
# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd,
# *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS = *.c \
*.cc \
@@ -928,7 +930,7 @@ EXCLUDE_SYMLINKS = NO
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS =
EXCLUDE_PATTERNS = */test/*
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
@@ -1265,9 +1267,9 @@ HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via Javascript. If disabled, the navigation index will
# are dynamically created via JavaScript. If disabled, the navigation index will
# consists of multiple levels of tabs that are statically embedded in every HTML
# page. Disable this option to support browsers that do not have Javascript,
# page. Disable this option to support browsers that do not have JavaScript,
# like the Qt help browser.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1555,8 +1557,14 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details.
FORMULA_MACROFILE =
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# https://www.mathjax.org) which uses client side Javascript for the rendering
# https://www.mathjax.org) which uses client side JavaScript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
@@ -1626,7 +1634,7 @@ MATHJAX_CODEFILE =
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There
# implemented using a web server instead of a web client using JavaScript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
# setting. When disabled, doxygen will generate a PHP script for searching and
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
@@ -1766,7 +1774,7 @@ PAPER_TYPE = a4
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
EXTRA_PACKAGES =
EXTRA_PACKAGES = amsmath
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
# generated LaTeX document. The header should contain everything until the first
@@ -2119,7 +2127,7 @@ ENABLE_PREPROCESSING = YES
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = NO
MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
@@ -2127,7 +2135,7 @@ MACRO_EXPANSION = NO
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = NO
EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
@@ -2159,7 +2167,7 @@ INCLUDE_FILE_PATTERNS =
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED =
PREDEFINED = __attribute__(x)=
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The

View File

@@ -30,7 +30,7 @@ Development is done with the following library versions:
| Cairographics | GLib2 | GTK3 |
| ------------- | ---------- | --------- |
| 1.17.3 | 2.60.6-1 | 3.24.10-1 |
| 1.17.2 | 2.64.2 | 3.24.18 |
@section comp-instr Compilation Instructions
@subsection linux-build General Linux Build Instruction
@@ -47,7 +47,7 @@ Once cmake has finished, type
make
@endcode
to build the program and
@code
make documentation
@endcode
@@ -59,7 +59,7 @@ The subfolder 'AUR' contains a PKGBUILD file to build an Archlinux/Pacman packag
@subsection comp-warnings Compiler Warnings
The compiler will throw the following warnings. Compiled with GCC 8.2.1.
The compiler will throw the following warnings. Compiled with GCC 9.3.0.
| Warning | Assessment |
| ------- | ---------- |

View File

@@ -2,14 +2,25 @@
* @defgroup ExternalRenderer External Shared Object Renderer
* @ingroup GdsOutputRenderer
*
* @subsection ExternalRendererProps Properties
* @section ExternalRendererProps Properties
* This class inherits all properties from its parent @ref GdsOutputRenderer.
* In addition to that, it implements the following properties:
*
* Property Name | Description
* -----------------|----------------------------------------------------------------
* shared-object-path | Path to the shared object used for rendering
* param-string | Command line parameters passed to external renderer's init function
*
* All these properties have to be set for rendering.
*
* @section ExternalRendererFuncs Necessary Functions
*
* The following functions and variables are necessary for an external renderer to implement:
*
* Code Define | Prototype | Description
* ---------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------
* @ref EXTERNAL_LIBRARY_RENDER_FUNCTION | int EXTERNAL_LIBRARY_RENDER_FUNCTION(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale) | Render cell to output file
* @ref EXTERNAL_LIBRARY_INIT_FUNCTION | int EXTERNAL_LIBRARY_INIT_FUNCTION(const char *option_string, const char *version_string) | Init function. Executed before rendering. This is given the command line parameters specified for the external renderer and the version string of the currently running gds-render program.
* @ref EXTERNAL_LIBRARY_FORK_REQUEST | int EXTERNAL_LIBRARY_FORK_REQUEST; | The pure presence of this integer results in the execution inside a subprocess of hte whole shared object's code
*
*/

View File

@@ -9,13 +9,13 @@
* @warning Although the GdsOutputRenderer class provides compatibility for asynchronous rendering,
* the class is not thread safe / re-entrant. Only use it from a signle context. Not even the rendering function called is allowed to modifiy this object.
*
* A allowed function to be called from the async rendering thread is #gds_output_renderer_update_gui_status_from_async and the get functions for the properties.
* A allowed function to be called from the async rendering thread is #gds_output_renderer_update_async_progress and the get functions for the properties.
*
* @note The context that owned the renderer has to ensure that only one rendering is active at a time for a single instance of a renderer.
*
* By default this class implements the following features:
*
* @subsection GdsOutputRendererProps Properties
* @section GdsOutputRendererProps Properties
* Property Name | Description
* -----------------|----------------------------------------------------------------
* layer-settings | LayerSettings object containing the layer rendering information
@@ -23,7 +23,7 @@
*
* All these properties have to be set for rendering.
*
* @subsection GdsOutputRendererSignals Signals / Events
* @section GdsOutputRendererSignals Signals / Events
* Signal Name | Description | Callback prototype
* -----------------|-------------------------------------------------|-----------------------------------------------------------
* async-finished | The asynchronous rendering is finished | void callback(GdsOutputRenderer *src, gpointer user_data)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -4,7 +4,7 @@
*
* This is the class implementing the \f$\mbox{\LaTeX}\f$ / TikZ output rendering
* @subsection LaTeXRendererProps Properties
* @section LaTeXRendererProps Properties
* This class inherits all properties from its parent @ref GdsOutputRenderer.
* In addition to that, it implements the following properties:
*

6
doxygen/plugins.dox Normal file
View File

@@ -0,0 +1,6 @@
/**
* @defgroup plugins External Renderer Plugins
*
* These plugins can be loaded with the @ref ExternalRenderer
*
*/

View File

@@ -4,24 +4,24 @@
To use the application on the command line check 'gds-render `--`help'.
Usage:
gds-render [OPTION…] FILE - Convert GDS file <FILE> to graphic
gds-render [OPTION…] FILE - Convert GDS file `<FILE>` to graphic
Help Options:
-h, '--'help Show help options
'--'help-all Show all help options
'--'help-gtk Show GTK+ Options
Application Options:
-v, '--'version Print version
-r, '--'renderer=pdf|svg|tikz|ext Renderer to use
-s, '--'scale=<SCALE> Divide output coordinates by <SCALE>
-o, '--'output-file=PATH Output file path
-m, '--'mapping=PATH Path for Layer Mapping File
-c, '--'cell=NAME Cell to render
-a, '--'tex-standalone Create standalone PDF
-l, '--'tex-layers Create PDF Layers (OCG)
-P, '--'custom-render-lib=PATH Path to a custom shared object, that implements the render_cell_to_file function
'--'display=DISPLAY X display to use
Help Options:
-h, `--`help Show help options
`--`help-all Show all help options
`--`help-gtk Show GTK+ Options
Application Options:
-v, `--`version Print version
-r, `--`renderer=pdf|svg|tikz|ext Renderer to use
-s, `--`scale=`<SCALE>` Divide output coordinates by `<SCALE>`
-o, `--`output-file=PATH Output file path
-m, `--`mapping=PATH Path for Layer Mapping File
-c, `--`cell=NAME Cell to render
-a, `--`tex-standalone Create standalone PDF
-l, `--`tex-layers Create PDF Layers (OCG)
-P, `--`custom-render-lib=PATH Path to a custom shared object, that implements the render_cell_to_file function
`--`display=DISPLAY X display to use
@section gui Graphical User Interface
@@ -33,8 +33,8 @@ It is possible to export the layer configurations so they can be used later on.
@image html gui.png
@image latex gui.png
The cell selector on the left shows the GDS Libraries and Cells. The cells are marked green if all references inside the cell could be found. If not all references could be found, the cell is marked orange. This doens't show if child cells have missing childs. Only one level of the hierarchy is checked in order to make it easier to spot an errorneous cell. Cells with missing child cells are still renderable but '--' obviously '--' faulty. If a cell or any sub-cell contains a reference loop, the cell is marked red. In this case it can't be selected for rendering.
In the above image the cell is green; so everything is okay.
The cell selector on the left shows the GDS Libraries and Cells. The cells are marked green if all references inside the cell could be found. If not all references could be found, the cell is marked orange. This doens't show if child cells have missing childs. Only one level of the hierarchy is checked in order to make it easier to spot an errorneous cell. Cells with missing child cells are still renderable but `--` obviously `--` faulty. If a cell or any sub-cell contains a reference loop, the cell is marked red. In this case it can't be selected for rendering.
In the above image one cell is green; so everything is okay. And the other one is red, which indicates a reference loop. This cell cannot be selected for rendering!
*/

View File

@@ -2,10 +2,10 @@
@page versioning Version Number
@section main-version Main Versioning Scheme
The version number of this application consists of a given version in the format of 'v1.0'.
Where the first number indicates a major release and the second number indicates minor changes.
The version number of this application consists of a given version in the format of 'v1.0.0' (formely only 2 digits).
Where the first number indicates a major release and the second and third numbers indicate minor changes.
Versions, including release candidates and path-levels, are tagged in git.
Versions, including release candidates and patch-levels, are tagged in git.
@subsection rc Release Candidates
Release candidates are software versions that seem stable and functional to become a new version but testing is not fully finished. These versions are marked with an '-rcX', where X is the number of the release candidate.
@@ -13,7 +13,7 @@ The 3rd release candidate of version 4.2 would be '*v4.2-rc3*'.
Release candidates are in a frozen state. Only bugfixes that are necessary for functionality are applied to these versions before releasing the final version.
@subsection patch-level Patch Levels
If an already released version contains bugs that need to be fixed, the version number is not incremented. Insted a new version number with a patch-level is created. The patch-level is appended with a dash directly after the version number. The fist patch-level of version 3.5 would be: 'v3.5-1'.
If an already released version contains bugs that need to be fixed, the version number is not incremented. Insted a new version number with a patch-level is created. The patch-level is appended with a dash directly after the version number. The fist patch-level of version 3.5.2 would be: 'v3.5.2-1'.
@section git-version-num Git Based Version Number

View File

@@ -29,13 +29,13 @@
#include <stdio.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <gds-render/gds-render-gui.h>
#include <gds-render/gds-utils/gds-parser.h>
#include <gds-render/gds-utils/gds-tree-checker.h>
#include <gds-render/layer/layer-selector.h>
#include <gds-render/widgets/activity-bar.h>
#include <gds-render/cell-selector/tree-store.h>
#include <gds-render/cell-selector/lib-cell-renderer.h>
#include <gds-render/output-renderers/latex-renderer.h>
#include <gds-render/output-renderers/cairo-renderer.h>
@@ -43,6 +43,14 @@
#include <gds-render/geometric/cell-geometrics.h>
#include <gds-render/version.h>
/** @brief Columns of selection tree view */
enum cell_store_columns {
CELL_SEL_LIBRARY = 0,
CELL_SEL_CELL,
CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */
CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */
};
enum gds_render_gui_signal_sig_ids {SIGNAL_WINDOW_CLOSED = 0, SIGNAL_COUNT};
static guint gds_render_gui_signals[SIGNAL_COUNT];
@@ -64,6 +72,7 @@ struct _GdsRenderGui {
GtkWidget *save_layer_button;
GtkWidget *select_all_button;
GtkTreeStore *cell_tree_store;
GtkTreeModelFilter *cell_filter;
GtkWidget *cell_search_entry;
LayerSelector *layer_selector;
GtkTreeView *cell_tree_view;
@@ -106,22 +115,144 @@ static gboolean on_window_close(gpointer window, GdkEvent *event, gpointer user)
}
/**
* @brief generate string from gds_time_field
* @param date Date to convert
* @return String with date
* @brief This function only allows valid cells to be selected
* @param selection
* @param model
* @param path
* @param path_currently_selected
* @param data
* @return TRUE if element is selectable, FALSE if not
*/
static GString *generate_string_from_date(struct gds_time_field *date)
static gboolean tree_sel_func(GtkTreeSelection *selection,
GtkTreeModel *model,
GtkTreePath *path,
gboolean path_currently_selected,
gpointer data)
{
GString *str;
GtkTreeIter iter;
struct gds_cell *cell;
unsigned int error_level;
gboolean ret = FALSE;
(void)selection;
(void)path_currently_selected;
(void)data;
str = g_string_new_len(NULL, 50);
g_string_printf(str, "%02u.%02u.%u - %02u:%02u",
(unsigned int)date->day,
(unsigned int)date->month,
(unsigned int)date->year,
(unsigned int)date->hour,
(unsigned int)date->minute);
return str;
gtk_tree_model_get_iter(model, &iter, path);
gtk_tree_model_get(model, &iter, CELL_SEL_CELL, &cell, CELL_SEL_CELL_ERROR_STATE, &error_level, -1);
/* Allow only rows with _valid_ cell to be selected */
if (cell) {
/* Cell available. Check if it passed the critical checks */
if (!(error_level & LIB_CELL_RENDERER_ERROR_ERR))
ret = TRUE;
}
return ret;
}
/**
* @brief Trigger refiltering of cell filter
* @param entry Unused widget, that emitted the signal
* @param data GdsrenderGui self instance
*/
static void cell_tree_view_change_filter(GtkWidget *entry, gpointer data)
{
GdsRenderGui *self = RENDERER_GUI(data);
(void)entry;
gtk_tree_model_filter_refilter(self->cell_filter);
}
/**
* @brief cell_store_filter_visible_func Decides whether an element of the tree model @p model is visible.
* @param model Tree model
* @param iter Current element / iter in Model to check
* @param data Data. Set to static stores variable
* @return TRUE if visible, else FALSE
* @note TODO: Maybe implement Damerau-Levenshtein distance matching
*/
static gboolean cell_store_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
{
GdsRenderGui *self;
struct gds_cell *cell;
struct gds_library *lib;
gboolean result = FALSE;
const char *search_string;
self = RENDERER_GUI(data);
g_return_val_if_fail(RENDERER_IS_GUI(self), FALSE);
if (!model || !iter)
goto exit_filter;
gtk_tree_model_get(model, iter, CELL_SEL_CELL, &cell, CELL_SEL_LIBRARY, &lib, -1);
/* Show always, if this is a pure lib entry */
if (lib && !cell) {
result = TRUE;
goto exit_filter;
}
if (!cell)
goto exit_filter;
search_string = gtk_entry_get_text(GTK_ENTRY(self->cell_search_entry));
/* Show all, if field is empty */
if (!strlen(search_string))
result = TRUE;
if (strstr(cell->name, search_string))
result = TRUE;
gtk_tree_view_expand_all(self->cell_tree_view);
exit_filter:
return result;
}
/**
* @brief Setup a GtkTreeView with the necessary columns
* @param self Current GUI object
*/
int gds_render_gui_setup_cell_selector(GdsRenderGui *self)
{
GtkCellRenderer *render_cell;
GtkCellRenderer *render_lib;
GtkTreeViewColumn *column;
self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER,
G_TYPE_POINTER, G_TYPE_UINT);
/* Searching */
self->cell_filter = GTK_TREE_MODEL_FILTER(
gtk_tree_model_filter_new(GTK_TREE_MODEL(self->cell_tree_store), NULL));
gtk_tree_model_filter_set_visible_func(self->cell_filter,
(GtkTreeModelFilterVisibleFunc)cell_store_filter_visible_func,
self, NULL);
g_signal_connect(GTK_SEARCH_ENTRY(self->cell_search_entry), "search-changed",
G_CALLBACK(cell_tree_view_change_filter), self);
gtk_tree_view_set_model(self->cell_tree_view, GTK_TREE_MODEL(self->cell_filter));
render_cell = lib_cell_renderer_new();
render_lib = lib_cell_renderer_new();
column = gtk_tree_view_column_new_with_attributes(_("Library"), render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL);
gtk_tree_view_append_column(self->cell_tree_view, column);
column = gtk_tree_view_column_new_with_attributes(_("Cell"), render_cell, "gds-cell", CELL_SEL_CELL,
"error-level", CELL_SEL_CELL_ERROR_STATE, NULL);
gtk_tree_view_append_column(self->cell_tree_view, column);
/* Callback for selection
* This prevents selecting a library
*/
gtk_tree_selection_set_select_function(gtk_tree_view_get_selection(self->cell_tree_view),
tree_sel_func, NULL, NULL);
return 0;
}
/**
@@ -145,25 +276,23 @@ static void on_load_gds(gpointer button, gpointer user)
gint dialog_result;
int gds_result;
char *filename;
GString *mod_date;
GString *acc_date;
unsigned int cell_error_level;
self = RENDERER_GUI(user);
if (!self)
return;
open_dialog = gtk_file_chooser_dialog_new("Open GDSII File", self->main_window,
open_dialog = gtk_file_chooser_dialog_new(_("Open GDSII File"), self->main_window,
GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL,
"Open GDSII", GTK_RESPONSE_ACCEPT,
_("Cancel"), GTK_RESPONSE_CANCEL,
_("Open GDSII"), GTK_RESPONSE_ACCEPT,
NULL);
file_chooser = GTK_FILE_CHOOSER(open_dialog);
/* Add GDS II Filter */
filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*.gds");
gtk_file_filter_set_name(filter, "GDSII-Files");
gtk_file_filter_set_name(filter, _("GDSII-Files"));
gtk_file_chooser_add_filter(file_chooser, filter);
dialog_result = gtk_dialog_run(GTK_DIALOG(open_dialog));
@@ -194,30 +323,17 @@ static void on_load_gds(gpointer button, gpointer user)
/* Create top level iter */
gtk_tree_store_append(self->cell_tree_store, &libiter, NULL);
/* Convert dates to String */
mod_date = generate_string_from_date(&gds_lib->mod_time);
acc_date = generate_string_from_date(&gds_lib->access_time);
gtk_tree_store_set(self->cell_tree_store, &libiter,
CELL_SEL_LIBRARY, gds_lib,
CELL_SEL_MODDATE, mod_date->str,
CELL_SEL_ACCESSDATE, acc_date->str,
-1);
/* Check this library. This might take a while */
(void)gds_tree_check_cell_references(gds_lib);
(void)gds_tree_check_reference_loops(gds_lib);
/* Delete GStrings including string data. */
/* Cell store copies String type data items */
g_string_free(mod_date, TRUE);
g_string_free(acc_date, TRUE);
for (cell = gds_lib->cells; cell != NULL; cell = cell->next) {
gds_c = (struct gds_cell *)cell->data;
gtk_tree_store_append(self->cell_tree_store, &celliter, &libiter);
/* Convert dates to String */
mod_date = generate_string_from_date(&gds_c->mod_time);
acc_date = generate_string_from_date(&gds_c->access_time);
/* Get the checking results for this cell */
cell_error_level = 0;
@@ -231,15 +347,9 @@ static void on_load_gds(gpointer button, gpointer user)
/* Add cell to tree store model */
gtk_tree_store_set(self->cell_tree_store, &celliter,
CELL_SEL_CELL, gds_c,
CELL_SEL_MODDATE, mod_date->str,
CELL_SEL_ACCESSDATE, acc_date->str,
CELL_SEL_CELL_ERROR_STATE, cell_error_level,
CELL_SEL_LIBRARY, gds_c->parent_library,
-1);
/* Delete GStrings including string data. */
/* Cell store copies String type data items */
g_string_free(mod_date, TRUE);
g_string_free(acc_date, TRUE);
} /* for cells */
} /* for libraries */
@@ -295,7 +405,9 @@ static void async_rendering_finished_callback(GdsOutputRenderer *renderer, gpoin
g_object_unref(renderer);
}
static void async_rendering_status_update_callback(GdsOutputRenderer *renderer, const char *status_message, gpointer data)
static void async_rendering_status_update_callback(GdsOutputRenderer *renderer,
const char *status_message,
gpointer data)
{
GdsRenderGui *gui;
(void)renderer;
@@ -440,21 +552,13 @@ static void on_convert_clicked(gpointer button, gpointer user)
g_signal_connect(render_engine, "async-finished", G_CALLBACK(async_rendering_finished_callback),
self);
activity_bar_set_busy(self->activity_status_bar, "Rendering cell...");
/* TODO: Replace this with asynchronous rendering. However, this fixes issue #19 */
activity_bar_set_busy(self->activity_status_bar, _("Rendering cell..."));
g_signal_connect(render_engine, "progress-changed",
G_CALLBACK(async_rendering_status_update_callback), self);
gds_output_renderer_render_output_async(render_engine, cell_to_render, sett->scale);
//self->button_state_data.rendering_active = FALSE;
//g_object_unref(render_engine);
}
g_free(file_name);
} else {
gtk_widget_destroy(dialog);
}
@@ -536,6 +640,7 @@ static void gds_render_gui_dispose(GObject *gobject)
g_clear_object(&self->convert_button);
g_clear_object(&self->layer_selector);
g_clear_object(&self->cell_tree_store);
g_clear_object(&self->cell_filter);
g_clear_object(&self->cell_search_entry);
g_clear_object(&self->activity_status_bar);
g_clear_object(&self->palette);
@@ -586,6 +691,38 @@ static void on_select_all_layers_clicked(GtkWidget *button, gpointer user_data)
layer_selector_select_all_layers(gui->layer_selector, TRUE);
}
static void auto_naming_clicked(GtkWidget *button, gpointer user_data)
{
GdsRenderGui *gui;
GtkDialog *dialog;
gboolean overwrite;
int dialog_result;
(void)button;
gui = RENDERER_GUI(user_data);
/* Don't do anything if the selector is empty. */
if (!layer_selector_contains_elements(gui->layer_selector))
return;
/* Ask for overwrite */
dialog = GTK_DIALOG(gtk_message_dialog_new(gui->main_window, GTK_DIALOG_USE_HEADER_BAR, GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO, "Overwrite existing layer names?"));
dialog_result = gtk_dialog_run(dialog);
switch (dialog_result) {
case GTK_RESPONSE_YES:
overwrite = TRUE;
break;
case GTK_RESPONSE_NO: /* Expected fallthrough */
default:
overwrite = FALSE;
break;
}
gtk_widget_destroy(GTK_WIDGET(dialog));
layer_selector_auto_name_layers(gui->layer_selector, overwrite);
}
GtkWindow *gds_render_gui_get_main_window(GdsRenderGui *gui)
{
return gui->main_window;
@@ -596,20 +733,18 @@ static void gds_render_gui_init(GdsRenderGui *self)
GtkBuilder *main_builder;
GtkWidget *listbox;
GtkHeaderBar *header_bar;
struct tree_stores *cell_selector_stores;
GtkWidget *sort_up_button;
GtkWidget *sort_down_button;
GtkWidget *activity_bar_box;
GtkWidget *auto_color_button;
GtkWidget *auto_naming_button;
main_builder = gtk_builder_new_from_resource("/gui/main.glade");
self->cell_tree_view = GTK_TREE_VIEW(gtk_builder_get_object(main_builder, "cell-tree"));
self->cell_search_entry = GTK_WIDGET(gtk_builder_get_object(main_builder, "cell-search"));
cell_selector_stores = setup_cell_selector(self->cell_tree_view, GTK_ENTRY(self->cell_search_entry));
self->cell_tree_store = cell_selector_stores->base_store;
gds_render_gui_setup_cell_selector(self);
self->main_window = GTK_WINDOW(gtk_builder_get_object(main_builder, "main-window"));
self->open_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-load-gds"));
@@ -672,6 +807,10 @@ static void gds_render_gui_init(GdsRenderGui *self)
self->select_all_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-select-all"));
g_signal_connect(self->select_all_button, "clicked", G_CALLBACK(on_select_all_layers_clicked), self);
/* Setup auto naming button */
auto_naming_button = GTK_WIDGET(gtk_builder_get_object(main_builder, "button-auto-name"));
g_signal_connect(auto_naming_button, "clicked", G_CALLBACK(auto_naming_clicked), self);
g_object_unref(main_builder);
/* Setup default button sensibility data */
@@ -683,10 +822,9 @@ static void gds_render_gui_init(GdsRenderGui *self)
g_object_ref(self->main_window);
g_object_ref(self->cell_tree_view);
g_object_ref(self->convert_button);
g_object_ref(self->layer_selector);
g_object_ref(self->cell_tree_store);
/* g_object_ref(self->layer_selector); <= This is already referenced by the _new() function */
g_object_ref(self->cell_search_entry);
g_object_ref(self->palette);
/* g_object_ref(self->palette); */
g_object_ref(self->open_button);
g_object_ref(self->load_layer_button);
g_object_ref(self->save_layer_button);

View File

@@ -40,6 +40,7 @@
#include <stdbool.h>
#include <math.h>
#include <cairo.h>
#include <glib/gi18n.h>
#include <gds-render/gds-utils/gds-parser.h>
@@ -79,6 +80,7 @@ enum gds_record {
STRANS = 0x1A01,
BOX = 0x2D00,
LAYER = 0x0D02,
DATATYPE = 0x0E02,
WIDTH = 0x0F03,
PATHTYPE = 0x2102,
COLROW = 0x1302,
@@ -217,7 +219,7 @@ static signed int gds_convert_signed_int(const char *data)
int ret;
if (!data) {
GDS_ERROR("This should not happen");
GDS_ERROR("Conversion from GDS data to signed int failed.");
return 0;
}
@@ -248,7 +250,7 @@ static int16_t gds_convert_signed_int16(const char *data)
* @param data Buffer containing the uint16
* @return result
*/
static uint16_t gds_convert_unsigend_int16(const char *data)
static uint16_t gds_convert_unsigned_int16(const char *data)
{
if (!data) {
GDS_ERROR("This should not happen");
@@ -283,13 +285,13 @@ static GList *append_library(GList *curr_list, struct gds_library **library_ptr)
}
/**
* @brief Append graphics to list
* @brief Prepend graphics to list
* @param curr_list List containing gds_graphics elements. May be NULL
* @param type Type of graphics
* @param graphics_ptr newly created graphic is written here
* @return new list pointer
*/
static GList *append_graphics(GList *curr_list, enum graphics_type type,
static __attribute__((warn_unused_result)) GList *prepend_graphics(GList *curr_list, enum graphics_type type,
struct gds_graphics **graphics_ptr)
{
struct gds_graphics *gfx;
@@ -308,7 +310,7 @@ static GList *append_graphics(GList *curr_list, enum graphics_type type,
if (graphics_ptr)
*graphics_ptr = gfx;
return g_list_append(curr_list, gfx);
return g_list_prepend(curr_list, gfx);
}
/**
@@ -541,17 +543,17 @@ static void gds_parse_date(const char *buffer, int length, struct gds_time_field
}
for (temp_date = mod_date; 1; temp_date = access_date) {
temp_date->year = gds_convert_unsigend_int16(buffer);
temp_date->year = gds_convert_unsigned_int16(buffer);
buffer += 2;
temp_date->month = gds_convert_unsigend_int16(buffer);
temp_date->month = gds_convert_unsigned_int16(buffer);
buffer += 2;
temp_date->day = gds_convert_unsigend_int16(buffer);
temp_date->day = gds_convert_unsigned_int16(buffer);
buffer += 2;
temp_date->hour = gds_convert_unsigend_int16(buffer);
temp_date->hour = gds_convert_unsigned_int16(buffer);
buffer += 2;
temp_date->minute = gds_convert_unsigend_int16(buffer);
temp_date->minute = gds_convert_unsigned_int16(buffer);
buffer += 2;
temp_date->second = gds_convert_unsigend_int16(buffer);
temp_date->second = gds_convert_unsigned_int16(buffer);
buffer += 2;
if (temp_date == access_date)
@@ -597,7 +599,7 @@ static void convert_aref_to_sref(struct gds_cell_array_instance *aref, struct gd
/* Iterate over columns and rows */
for (col = 0; col < aref->columns; col++) {
for (row = 0; row < aref->rows; row++) {
/* Create new instance for this row/column and aconfigure data */
/* Create new instance for this row/column and configure data */
container_cell->child_cells = append_cell_ref(container_cell->child_cells, &sref_inst);
if (!sref_inst) {
GDS_ERROR("Appending cell ref failed!");
@@ -666,7 +668,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
break;
}
rec_data_length = gds_convert_unsigend_int16(workbuff);
rec_data_length = gds_convert_unsigned_int16(workbuff);
if (rec_data_length < 4) {
/* Possible Zero-Padding: */
@@ -689,7 +691,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
GDS_ERROR("Unexpected end of file");
break;
}
rec_type = gds_convert_unsigend_int16(workbuff);
rec_type = gds_convert_unsigned_int16(workbuff);
/* if begin: Allocate structures */
@@ -759,8 +761,10 @@ int parse_gds_from_file(const char *filename, GList **library_list)
run = -3;
break;
}
current_cell->graphic_objs = append_graphics(current_cell->graphic_objs,
(rec_type == BOUNDARY ? GRAPHIC_POLYGON : GRAPHIC_BOX),
current_cell->graphic_objs = prepend_graphics(current_cell->graphic_objs,
(rec_type == BOUNDARY
? GRAPHIC_POLYGON
: GRAPHIC_BOX),
&current_graphics);
if (current_cell->graphic_objs == NULL) {
GDS_ERROR("Memory allocation failed");
@@ -791,7 +795,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
run = -3;
break;
}
current_cell->graphic_objs = append_graphics(current_cell->graphic_objs,
current_cell->graphic_objs = prepend_graphics(current_cell->graphic_objs,
GRAPHIC_PATH, &current_graphics);
if (current_cell->graphic_objs == NULL) {
GDS_ERROR("Memory allocation failed");
@@ -864,6 +868,7 @@ int parse_gds_from_file(const char *filename, GList **library_list)
case LIBNAME:
case SNAME:
case LAYER:
case DATATYPE:
case STRNAME:
break;
default:
@@ -1000,6 +1005,16 @@ int parse_gds_from_file(const char *filename, GList **library_list)
}
GDS_INF("\t\tAdded layer %d\n", (int)current_graphics->layer);
break;
case DATATYPE:
if (!current_graphics) {
GDS_WARN("Datatype has to be defined inside graphics object. Probably unknown object. Implement it yourself!");
break;
}
current_graphics->datatype = gds_convert_signed_int16(workbuff);
if (current_graphics->datatype < 0)
GDS_WARN("Datatype negative!");
GDS_INF("\t\tAdded datatype %d\n", (int)current_graphics->datatype);
break;
case MAG:
if (rec_data_length != 8) {
GDS_WARN("Magnification is not an 8 byte real. Results may be wrong");

View File

@@ -34,7 +34,7 @@
*/
#include <stdio.h>
#include <glib/gi18n.h>
#include <gds-render/gds-utils/gds-tree-checker.h>
int gds_tree_check_cell_references(struct gds_library *lib)
@@ -54,7 +54,7 @@ int gds_tree_check_cell_references(struct gds_library *lib)
/* Check if this list element is broken. This should never happen */
if (!cell) {
fprintf(stderr, "Broken cell list item found. Will continue.\n");
fprintf(stderr, _("Broken cell list item found. Will continue.\n"));
continue;
}
@@ -68,7 +68,7 @@ int gds_tree_check_cell_references(struct gds_library *lib)
/* Check if broken. This should not happen */
if (!cell_inst) {
fprintf(stderr, "Broken cell list item found in cell %s. Will continue.\n",
fprintf(stderr, _("Broken cell list item found in cell %s. Will continue.\n"),
cell->name);
continue;
}
@@ -90,7 +90,8 @@ int gds_tree_check_cell_references(struct gds_library *lib)
* @param cell Cell to check for
* @return 0 if cell is not in list. 1 if cell is in list
*/
static int gds_tree_check_list_contains_cell(GList *list, struct gds_cell *cell) {
static int gds_tree_check_list_contains_cell(GList *list, struct gds_cell *cell)
{
GList *iter;
for (iter = list; iter != NULL; iter = g_list_next(iter)) {
@@ -177,12 +178,14 @@ int gds_tree_check_reference_loops(struct gds_library *lib)
res = gds_tree_check_iterate_ref_and_check(cell_to_check, &visited_cells);
if (visited_cells) {
/* If cell contains no loop, print error when list not empty.
/*
* If cell contains no loop, print error when list not empty.
* In case of a loop, it is completely normal that the list is not empty,
* due to the instant return from gds_tree_check_iterate_ref_and_check()
*/
if (res == 0)
fprintf(stderr, "Visited cell list should be empty. This is a bug. Please report this.\n");
fprintf(stderr,
_("Visited cell list should be empty. This is a bug. Please report this.\n"));
g_list_free(visited_cells);
visited_cells = NULL;
}

View File

@@ -33,11 +33,11 @@
#include <gds-render/geometric/bounding-box.h>
#define MIN(a,b) (((a) < (b)) ? (a) : (b)) /**< @brief Return smaller number */
#define MAX(a,b) (((a) > (b)) ? (a) : (b)) /**< @brief Return bigger number */
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) /**< @brief Return smaller number */
#define MAX(a, b) (((a) > (b)) ? (a) : (b)) /**< @brief Return bigger number */
#define ABS_DBL(a) ((a) < 0 ? -(a) : (a))
void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box)
void bounding_box_calculate_from_polygon(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box)
{
double xmin = DBL_MAX, xmax = -DBL_MAX, ymin = DBL_MAX, ymax = -DBL_MAX;
struct vector_2d temp_vec;
@@ -68,7 +68,7 @@ void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t
box->vectors.upper_right.y = ymax;
}
void bounding_box_update_box(union bounding_box *destination, union bounding_box *update)
void bounding_box_update_with_box(union bounding_box *destination, union bounding_box *update)
{
if (!destination || !update)
return;
@@ -145,14 +145,12 @@ static void calculate_path_miter_points(struct vector_2d *a, struct vector_2d *b
vector_2d_subtract(m2, m2, &v_vec);
}
void bounding_box_calculate_path_box(GList *vertices, double thickness,
void bounding_box_update_with_path(GList *vertices, double thickness,
conv_generic_to_vector_2d_t conv_func, union bounding_box *box)
{
GList *vertex_iterator;
struct vector_2d pt;
printf("Warning! Function bounding_box_calculate_path_box not yet implemented correctly!\n");
if (!vertices || !box)
return;
@@ -173,7 +171,7 @@ void bounding_box_calculate_path_box(GList *vertices, double thickness,
}
}
void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt)
void bounding_box_update_with_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt)
{
struct vector_2d point;
@@ -191,24 +189,40 @@ void bounding_box_update_point(union bounding_box *destination, conv_generic_to_
destination->vectors.upper_right.y = MAX(destination->vectors.upper_right.y, point.y);
}
/**
* @brief Apply transformations onto bounding box.
* @param scale Scaling factor
* @param rotation_deg Roation of bounding box around the origin in degrees (counterclockwise)
* @param flip_at_x Flip the boundig box on the x axis before rotating.
* @param box Bounding box the operations should be applied to.
*/
void bounding_box_get_all_points(struct vector_2d *points, union bounding_box *box)
{
if (!points || !box)
return;
points[0].x = box->vectors.lower_left.x;
points[0].y = box->vectors.lower_left.y;
points[1].x = box->vectors.upper_right.x;
points[1].y = box->vectors.lower_left.y;
points[2].x = box->vectors.upper_right.x;
points[2].y = box->vectors.upper_right.y;
points[3].x = box->vectors.lower_left.x;
points[3].y = box->vectors.upper_right.y;
}
void bounding_box_apply_transform(double scale, double rotation_deg, bool flip_at_x, union bounding_box *box)
{
int i;
struct vector_2d input_points[4];
/* Due to linearity, the order of the operations does not matter.
* flip must be applied before rotation as defined by the GDS format
*/
for (i = 0; i < 2; i++) {
box->vector_array[i].y *= (flip_at_x ? -1 : 1);
vector_2d_rotate(&box->vector_array[i], rotation_deg * M_PI / 180);
vector_2d_scale(&box->vector_array[i], scale);
if (!box)
return;
bounding_box_get_all_points(input_points, box);
/* Reset box */
bounding_box_prepare_empty(box);
for (i = 0; i < 4; i++) {
input_points[i].y *= (flip_at_x ? -1 : 1);
vector_2d_rotate(&input_points[i], rotation_deg * M_PI / 180.0);
vector_2d_scale(&input_points[i], scale);
bounding_box_update_with_point(box, NULL, &input_points[i]);
}
}

View File

@@ -53,7 +53,7 @@ static void update_box_with_gfx(union bounding_box *box, struct gds_graphics *gf
case GRAPHIC_BOX:
/* Expected fallthrough */
case GRAPHIC_POLYGON:
bounding_box_calculate_polygon(gfx->vertices,
bounding_box_calculate_from_polygon(gfx->vertices,
(conv_generic_to_vector_2d_t)&convert_gds_point_to_2d_vector,
&current_box);
break;
@@ -63,7 +63,7 @@ static void update_box_with_gfx(union bounding_box *box, struct gds_graphics *gf
* Please be aware if paths are the outmost elements of your cell.
* You might end up with a completely wrong calculated cell size.
*/
bounding_box_calculate_path_box(gfx->vertices, gfx->width_absolute,
bounding_box_update_with_path(gfx->vertices, gfx->width_absolute,
(conv_generic_to_vector_2d_t)&convert_gds_point_to_2d_vector,
&current_box);
break;
@@ -74,7 +74,7 @@ static void update_box_with_gfx(union bounding_box *box, struct gds_graphics *gf
}
/* Update box with results */
bounding_box_update_box(box, &current_box);
bounding_box_update_with_box(box, &current_box);
}
void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell)
@@ -113,7 +113,7 @@ void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell)
temp_box.vectors.upper_right.y += sub_cell->origin.y;
/* update the parent's box */
bounding_box_update_box(box, &temp_box);
bounding_box_update_with_box(box, &temp_box);
}
}

View File

@@ -46,9 +46,10 @@ double vector_2d_scalar_multipy(struct vector_2d *a, struct vector_2d *b)
void vector_2d_normalize(struct vector_2d *vec)
{
double len;
if (!vec)
return;
len = sqrt(pow(vec->x,2)+pow(vec->y,2));
len = sqrt(pow(vec->x, 2) + pow(vec->y, 2));
vec->x = vec->x/len;
vec->y = vec->y/len;
}
@@ -64,7 +65,7 @@ void vector_2d_rotate(struct vector_2d *vec, double angle)
sin_val = sin(angle);
cos_val = cos(angle);
vector_2d_copy(&temp, vec);
(void)vector_2d_copy(&temp, vec);
/* Apply rotation matrix */
vec->x = (cos_val * temp.x) - (sin_val * temp.y);
@@ -97,9 +98,8 @@ struct vector_2d *vector_2d_alloc(void)
void vector_2d_free(struct vector_2d *vec)
{
if (vec) {
if (vec)
free(vec);
}
}
void vector_2d_scale(struct vector_2d *vec, double scale)
@@ -114,9 +114,9 @@ void vector_2d_scale(struct vector_2d *vec, double scale)
double vector_2d_abs(struct vector_2d *vec)
{
double len = 0.0;
if (vec) {
len = sqrt(pow(vec->x,2)+pow(vec->y,2));
}
if (vec)
len = sqrt(pow(vec->x, 2) + pow(vec->y, 2));
return len;
}
@@ -142,7 +142,7 @@ void vector_2d_subtract(struct vector_2d *res, struct vector_2d *a, struct vecto
void vector_2d_add(struct vector_2d *res, struct vector_2d *a, struct vector_2d *b)
{
if (res && a && b) {
res->x = a->x +b->x;
res->x = a->x + b->x;
res->y = a->y + b->y;
}
}

View File

@@ -1,57 +0,0 @@
/*
* GDSII-Converter
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file tree-store.h
* @brief Header file for Tree store implementation
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup GUI
* @{
*/
#ifndef __TREE_STORE_H__
#define __TREE_STORE_H__
#include <gtk/gtk.h>
/** @brief Columns of selection tree view */
enum cell_store_columns {
CELL_SEL_LIBRARY = 0,
CELL_SEL_CELL,
CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */
CELL_SEL_MODDATE,
CELL_SEL_ACCESSDATE,
CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */
};
struct tree_stores {
GtkTreeView *base_tree_view;
GtkTreeStore *base_store;
GtkTreeModelFilter *filter;
GtkEntry *search_entry;
};
struct tree_stores *setup_cell_selector(GtkTreeView* view, GtkEntry *search_entry);
#endif /* __TREE_STORE_H__ */
/** @} */

View File

@@ -33,6 +33,21 @@
#include <glib.h>
/**
* @brief External renderer paramameters to command line renderer
*/
struct external_renderer_params {
/**
* @brief Path to shared object
*/
char *so_path;
/**
* @brief Command line parameters given
*/
char *cli_params;
};
/**
* @brief Convert GDS according to command line parameters
* @param gds_name Path to GDS File
@@ -40,18 +55,18 @@
* @param renderers Renderer ids
* @param output_file_names Output file names
* @param layer_file Layer mapping file
* @param so_path Shared object
* @param ext_param Settings for external library renderer
* @param tex_standalone Standalone TeX
* @param tec_layers TeX OCR layers
* @param tex_layers TeX OCR layers
* @param scale Scale value
* @return Error code, 0 if successful
*/
int command_line_convert_gds(const char *gds_name,
const char *cell_name,
char **renderers,
char **output_file_names,
const char *layer_file,
const char *so_path,
const char *cell_name,
char **renderers,
char **output_file_names,
const char *layer_file,
struct external_renderer_params *ext_param,
gboolean tex_standalone,
gboolean tex_layers,
double scale);

View File

@@ -58,7 +58,7 @@ enum graphics_type
enum path_type {PATH_FLUSH = 0, PATH_ROUNDED = 1, PATH_SQUARED = 2}; /**< Path line caps */
/**
* @brief A point in the 2D plane. Sometimes reffered to as vertex
* @brief A point in the 2D plane. Sometimes referred to as vertex
*/
struct gds_point {
int x;
@@ -101,7 +101,7 @@ struct gds_graphics {
enum path_type path_render_type; /**< @brief Line cap */
int width_absolute; /**< @brief Width. Not used for objects other than paths */
int16_t layer; /**< @brief Layer the graphic object is on */
uint16_t datatype;
int16_t datatype; /**< @brief Data type of graphic object */
};
/**

View File

@@ -35,23 +35,118 @@
#include <gds-render/geometric/vector-operations.h>
#include <stdbool.h>
/**
* @brief Union describing a bounding box
*
* Two ways of accessing a bounding box are possible.
*
* Either, use the "named" vectors struct to specifically access the points
* @code
* lower_left = box.vectors.lower_left;
* upper right = box.vectors.upper_right;
* @endcode
*
* or use the iterable vector array:
* @code
* for (i = 0; i < 2; i++)
* box.vector_array[i] = points[i];
* @endcode
*/
union bounding_box {
/** Coordinate System is (y up | x right) */
/**
* @brief Location vectors of upper right and lower left bounding box points
* @note Coordinate System is (y up | x right)
*/
struct _vectors {
/** @brief Lower left point of the bounding box */
struct vector_2d lower_left;
/** @brief Upper right point of the bounding box */
struct vector_2d upper_right;
} vectors;
/**
* @brief Array of vectors representing a bounding box
* @note This is more convenient for iterating
*/
struct vector_2d vector_array[2];
};
/*
* @brief Pointer to a function that takes any pointer and converts this object to a vector_2d struct
*/
typedef void (*conv_generic_to_vector_2d_t)(void *, struct vector_2d *);
void bounding_box_calculate_polygon(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box);
void bounding_box_update_box(union bounding_box *destination, union bounding_box *update);
/**
* @brief Calculate bounding box of polygon
* @param vertices List of vertices that describe the polygon
* @param conv_func Conversion function to convert vertices to vector_2d structs.
* @param box Box to write to. This box is not updated! All previous data is discarded
*/
void bounding_box_calculate_from_polygon(GList *vertices, conv_generic_to_vector_2d_t conv_func, union bounding_box *box);
/**
* @brief Update an exisitng bounding box with another one.
* @param destination Target box to update
* @param update Box to update the target with
*/
void bounding_box_update_with_box(union bounding_box *destination, union bounding_box *update);
/**
* @brief Prepare an empty bounding box.
*
* Updating this specially prepared box, results in a bounding box that is the same size as the update
*
* @param box Box to preapre
*/
void bounding_box_prepare_empty(union bounding_box *box);
void bounding_box_update_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt);
/**
* @brief Update bounding box with a point
* @param destination Bounding box to update
* @param conv_func Conversion function to convert \p pt to a vector_2d. May be NULL
* @param pt Point to update bounding box with
*/
void bounding_box_update_with_point(union bounding_box *destination, conv_generic_to_vector_2d_t conv_func, void *pt);
/**
* @brief Return all four corner points of a bounding box
* @param[out] points Array of 4 vector_2d structs that has to be allocated by the caller
* @param box Bounding box
*/
void bounding_box_get_all_points(struct vector_2d *points, union bounding_box *box);
/**
* @brief Apply transformations onto bounding box.
*
* All corner points \f$ \vec{P_i} \f$ of the bounding box are transformed to output points \f$ \vec{P_o} \f$ by:
*
* \f$ \vec{P_o} = s \cdot \begin{pmatrix}\cos\left(\phi\right) & -\sin\left(\phi\right)\\ \sin\left(\phi\right) & \cos\left(\phi\right)\end{pmatrix} \cdot \begin{pmatrix} 1 & 0 \\ 0 & -1^{m} \end{pmatrix} \cdot \vec{P_i} \f$, with:
*
* * \f$s\f$: Scale
* * \f$m\f$: 1, if flipped_at_x is True, else 0
* * \f$\phi\f$: Rotation angle in radians. The conversion degrees => radians is done internally
*
* The result is the bounding box generated around all output points
*
* @param scale Scaling factor
* @param rotation_deg Rotation of bounding box around the origin in degrees (counterclockwise)
* @param flip_at_x Flip the boundig box on the x axis before rotating.
* @param box Bounding box the operations should be applied to.
* @note Keep in mind, that this bounding box is actually the bounding box of the rotated boundig box and not the object itself.
* It might be too big.
*/
void bounding_box_apply_transform(double scale, double rotation_deg, bool flip_at_x, union bounding_box *box);
void bounding_box_calculate_path_box(GList *vertices, double thickness, conv_generic_to_vector_2d_t conv_func, union bounding_box *box);
/**
* @brief Calculate the bounding box of a path and update the given bounding box
* @param vertices Vertices the path is made up of
* @param thickness Thisckness of the path
* @param conv_func Conversion function for vertices to vector_2d structs
* @param box Bounding box to write results in.
* @warning This function is not yet implemented correctly. Miter points of paths are not taken into account.
* If a path is the outmost object of your cell _and_ it is not parallel to one of the coordinate axes,
* the calculated bounding box size might be off. In other cases it should be reasonable close to the real bounding box.
*/
void bounding_box_update_with_path(GList *vertices, double thickness, conv_generic_to_vector_2d_t conv_func, union bounding_box *box);
#endif /* _BOUNDING_BOX_H_ */

View File

@@ -35,10 +35,17 @@
#include <gds-render/gds-utils/gds-types.h>
/**
* @brief calculate_cell_bounding_box Calculate bounding box of gds cell
* @param box Resulting boundig box. Will be uüdated and not overwritten
* @brief Calculate bounding box of a gds cell.
*
* This function updates a given bounding box with the dimensions of a
* gds_cell. Please note that the handling of path miter points is not complete yet.
* If a path object is the outmost object of your cell at any edge,
* the resulting bounding box might be the wrong size. The devistion from the real size
* is guaranteed to be within the width of the path object.
*
* @param box Resulting boundig box. Will be updated and not overwritten
* @param cell Toplevel cell
* @warning Path handling not yet implemented correctly.
* @warning Handling of Path graphic objects not yet implemented correctly.
*/
void calculate_cell_bounding_box(union bounding_box *box, struct gds_cell *cell);

View File

@@ -103,10 +103,33 @@ void layer_selector_select_all_layers(LayerSelector *layer_selector, gboolean se
* @brief Apply colors from palette to all layers. Aditionally set alpha
* @param layer_selector LayerSelector object
* @param palette Color palette to use
* @param global_alpha Additional alpha value that is applied to all layers
* @param global_alpha Additional alpha value that is applied to all layers. Must be > 0
*/
void layer_selector_auto_color_layers(LayerSelector *layer_selector, ColorPalette *palette, double global_alpha);
/**
* @brief Auto name all layers in the layer selector.
*
* This functions sets the name of the layer equal to its number.
* The \p overwrite parameter specifies if already set layer names are overwritten.
*
* @param layer_selector LayerSelector
* @param overwrite Overwrite existing layer names
*/
void layer_selector_auto_name_layers(LayerSelector *layer_selector, gboolean overwrite);
/**
* @brief Check if the given layer selector contains layer elements.
*
* This function checks whether there are elements present.
* If an invalid object pointer \p layer_selector is passed,
* the function returns FALSE
*
* @param[in] layer_selector Selector to check
* @return True, if there is at least one layer present inside the selector
*/
gboolean layer_selector_contains_elements(LayerSelector *layer_selector);
G_END_DECLS
#endif /* __LAYER_SELECTOR_H__ */

View File

@@ -18,8 +18,8 @@
*/
/**
* @file layer-info.h
* @brief LayerSettings class heade file
* @file layer-settings.h
* @brief LayerSettings class header file
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
@@ -41,7 +41,7 @@ struct layer_info
{
int layer; /**< @brief Layer number */
char *name; /**< @brief Layer name. */
int stacked_position; ///< @brief Position of layer in output @warning This parameter is not used by any renderer so far @note Lower is bottom, higher is top
int stacked_position; /**< @brief Position of layer in output @warning This parameter is not used by any renderer so far @note Lower is bottom, higher is top */
GdkRGBA color; /**< @brief RGBA color used to render this layer */
int render; /**< @brief true: Render to output */
};
@@ -96,8 +96,12 @@ int layer_settings_remove_layer(LayerSettings *settings, int layer);
GList *layer_settings_get_layer_info_list(LayerSettings *settings);
/**
* @brief Write layer settings to a CSV file
* @param path
* @brief Write layer settings to a CSV file.
*
* This function writes the layer settings to a CSV file according to the
* layer mapping specification (@ref lmf-spec)
* @param settings LayerSettings object
* @param path Output path for CSV file.
* @return 0 if successful
*/
int layer_settings_to_csv(LayerSettings *settings, const char *path);

View File

@@ -1,60 +0,0 @@
/*
* GDSII-Converter
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file mapping-parser.h
* @brief Function to read a mapping file line and parse it.
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
#ifndef __MAPPING_PARSER_H__
#define __MAPPING_PARSER_H__
/**
* @addtogroup Mapping-Parser
* @{
*/
#include <glib.h>
#include <gds-render/widgets/layer-element.h>
#include <gds-render/layer/layer-settings.h>
/**
* @brief Load a line from \p stream and parse try to parse it as layer information
* @param stream Input data stream
* @param export Layer shall be exported
* @param name Layer name. Free returned pointer after using.
* @param layer Layer number
* @param color RGBA color.
* @return 1 if malformatted line, 0 if parsing was successful and parameters are valid, -1 if file end
*/
int mapping_parser_load_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color);
/**
* @brief Create Line for LayerMapping file with supplied information
* @param layer_element information
* @param line_buffer buffer to write to
* @param max_len Maximum length that cna be used in \p line_buffer
*/
void mapping_parser_gen_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len);
/** @} */
#endif /* __MAPPING_PARSER_H__ */

View File

@@ -17,7 +17,7 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file cairo-output.h
* @file cairo-renderer.h
* @brief Header File for Cairo output renderer
* @author Mario Hüttel <mario.huettel@gmx.net>
*/

View File

@@ -0,0 +1,76 @@
/*
* GDSII-Converter
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __EXTERNAL_RENDERER_INTERFACES_H__
#define __EXTERNAL_RENDERER_INTERFACES_H__
#ifndef xstr
#define xstr(a) str(a)
#define str(a) #a
#endif /* xstr */
/**
* @addtogroup ExternalRenderer
* @{
*/
/**
* @brief This define is used to export a function from a shared object
*/
#define EXPORT_FUNC __attribute__((visibility("default")))
/**
* @brief Function name expected to be found in external library for rendering.
*
* The function has to be defined as follows:
* @code
* int EXTERNAL_LIBRARY_RENDER_FUNCTION(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale);
* @endcode
*/
#define EXTERNAL_LIBRARY_RENDER_FUNCTION exported_render_cell_to_file
/**
* @brief Function name expected to be found in external library for initialization.
*
* @code
* int EXTERNAL_LIBRARY_INIT_FUNCTION(const char *option_string, const char *version_string);
* @endcode
*/
#define EXTERNAL_LIBRARY_INIT_FUNCTION exported_init
/**
* @brief Global integer specified by an external renderer to signal, that the init and render functions shall be executed in a subprocess
*
* The pure presence of this symbol name causes forking. The content of this variable is don't care.
* @note Use this if you mess with the internal structures of gds-render
*/
#define EXTERNAL_LIBRARY_FORK_REQUEST exported_fork_request
/**
* @brief Define for declaring the exported functions.
*
* This not only helps with the declaration but also makes the symbols visible, so they can be called form outside the library
*/
#define EXPORTED_FUNC_DECL(FUNC) EXPORT_FUNC FUNC
/** @} */
#endif /* __EXTERNAL_RENDERER_INTERFACES_H__ */

View File

@@ -33,6 +33,7 @@
#include <gds-render/output-renderers/gds-output-renderer.h>
#include <gds-render/gds-utils/gds-types.h>
#include <gds-render/output-renderers/external-renderer-interfaces.h>
G_BEGIN_DECLS
@@ -40,16 +41,6 @@ G_BEGIN_DECLS
G_DECLARE_FINAL_TYPE(ExternalRenderer, external_renderer, GDS_RENDER, EXTERNAL_RENDERER, GdsOutputRenderer)
/**
* @brief function name expected to be found in external library.
*
* The function has to be defined as follows:
* @code
* int EXTERNAL_LIBRARY_FUNCTION(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale)
* @endcode
*/
#define EXTERNAL_LIBRARY_FUNCTION "render_cell_to_file"
/**
* @brief Create new ExternalRenderer object
* @return New object
@@ -59,9 +50,10 @@ ExternalRenderer *external_renderer_new();
/**
* @brief Create new ExternalRenderer object with specified shared object path
* @param so_path Path to shared object, the rendering function is searched in
* @param param_string Command line parameter string passed to external renderer
* @return New object.
*/
ExternalRenderer *external_renderer_new_with_so(const char *so_path);
ExternalRenderer *external_renderer_new_with_so_and_param(const char *so_path, const char *param_string);
G_END_DECLS

View File

@@ -152,7 +152,7 @@ int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct
* @param renderer GdsOutputrenderer object
* @param status Status to supply to signal emission
*/
void gds_output_renderer_update_gui_status_from_async(GdsOutputRenderer *renderer, const char *status);
void gds_output_renderer_update_async_progress(GdsOutputRenderer *renderer, const char *status);
G_END_DECLS

View File

@@ -18,7 +18,7 @@
*/
/**
* @file latex-output.h
* @file latex-renderer.h
* @brief LaTeX output renderer
* @author Mario Hüttel <mario.huettel@gmx.net>
*/

View File

@@ -26,17 +26,17 @@
#include <gds-render/layer/color-palette.h>
struct _ColorPalette {
/* Inheritance */
GObject parent;
/* Inheritance */
GObject parent;
/* Custom fields */
/** @brief The internal array to store the colors */
GdkRGBA *color_array;
/** @brief The length of the _ColorPalette::color_array array */
unsigned int color_array_length;
/* Custom fields */
/** @brief The internal array to store the colors */
GdkRGBA *color_array;
/** @brief The length of the _ColorPalette::color_array array */
unsigned int color_array_length;
/* Dummy bytes to ensure ABI compatibility in future versions */
gpointer dummy[4];
/* Dummy bytes to ensure ABI compatibility in future versions */
gpointer dummy[4];
};
G_DEFINE_TYPE(ColorPalette, color_palette, G_TYPE_OBJECT)
@@ -106,13 +106,13 @@ static int color_palette_fill_with_resource(ColorPalette *palette, char *resourc
char_array = (const char *)g_bytes_get_data(data, &byte_count);
if (!char_array || !byte_count)
goto ret_unref;
goto ret_unref_data;
/* Get maximum lenght of color palette, assuming all entries are valid */
lines = count_non_empty_lines_in_array(char_array, byte_count);
if (lines <= 0)
goto ret_unref;
goto ret_unref_data;
palette->color_array = (GdkRGBA *)malloc(sizeof(GdkRGBA) * (unsigned int)lines);
@@ -128,26 +128,28 @@ static int color_palette_fill_with_resource(ColorPalette *palette, char *resourc
color_idx = 0;
/* interate over lines and match */
for (idx = 0 ; idx < byte_count; idx++) {
for (idx = 0 ; (unsigned int)idx < byte_count; idx++) {
/* Fillup line. */
line[line_idx] = char_array[idx];
/* If end of line/string is reached, process */
if (line[line_idx] == '\n' || line[line_idx] == '\0') {
line[line_idx] = '\0';
/* Match the line */
g_regex_match(regex, line, 0, &mi);
if (g_match_info_matches(mi) && color_idx < lines) {
if (g_match_info_matches(mi) && color_idx < (unsigned int)lines) {
match = g_match_info_fetch_named(mi, "red");
palette->color_array[color_idx].red = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
palette->color_array[color_idx].red =
(double)g_ascii_strtoll(match, NULL, 16) / 255.0;
g_free(match);
match = g_match_info_fetch_named(mi, "green");
palette->color_array[color_idx].green = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
palette->color_array[color_idx].green =
(double)g_ascii_strtoll(match, NULL, 16) / 255.0;
g_free(match);
match = g_match_info_fetch_named(mi, "blue");
palette->color_array[color_idx].blue = (double)g_ascii_strtoll(match, NULL, 16) / 255.0;
palette->color_array[color_idx].blue =
(double)g_ascii_strtoll(match, NULL, 16) / 255.0;
g_free(match);
/* Only RGB supported so far. Fix alpha channel to 1.0 */
@@ -166,10 +168,10 @@ static int color_palette_fill_with_resource(ColorPalette *palette, char *resourc
continue;
}
/* increment line index. If end is reached write all bytes to the line end
* line is longer than required for parsing. This ensures, that everything works as expected
/* increment line index. If end is reached write all bytes to the line end.
* Line is longer than required for parsing. This ensures, that everything works as expected
*/
line_idx += (line_idx < sizeof(line)-1 ? 1 : 0);
line_idx += ((unsigned int)line_idx < sizeof(line)-1 ? 1 : 0);
}
/* Data read; Shrink array in case of invalid lines */
@@ -177,7 +179,7 @@ static int color_palette_fill_with_resource(ColorPalette *palette, char *resourc
palette->color_array_length = color_idx;
g_regex_unref(regex);
ret_unref:
ret_unref_data:
g_bytes_unref(data);
return 0;
@@ -233,10 +235,10 @@ static void color_palette_dispose(GObject *gobj)
ColorPalette *palette;
palette = GDS_RENDER_COLOR_PALETTE(gobj);
if (palette->color_array)
{
if (palette->color_array) {
palette->color_array_length = 0;
free(palette->color_array);
palette->color_array = NULL;
}
/* Chain up to parent class */

View File

@@ -36,7 +36,6 @@
#include <gds-render/layer/layer-selector.h>
#include <gds-render/gds-utils/gds-parser.h>
#include <gds-render/widgets/layer-element.h>
#include <gds-render/layer/mapping-parser.h>
struct _LayerSelector {
/* Parent */
@@ -55,7 +54,8 @@ struct _LayerSelector {
G_DEFINE_TYPE(LayerSelector, layer_selector, G_TYPE_OBJECT)
/* Drag and drop code
/*
* Drag and drop code
* Original code from https://blog.gtk.org/2017/06/01/drag-and-drop-in-lists-revisited/
*/
@@ -73,16 +73,16 @@ static void sel_layer_element_drag_begin(GtkWidget *widget, GdkDragContext *cont
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, alloc.width, alloc.height);
cr = cairo_create(surface);
gtk_style_context_add_class (gtk_widget_get_style_context(row), "drag-icon");
gtk_widget_draw (row, cr);
gtk_style_context_add_class(gtk_widget_get_style_context(row), "drag-icon");
gtk_widget_draw(row, cr);
gtk_style_context_remove_class(gtk_widget_get_style_context(row), "drag-icon");
gtk_widget_translate_coordinates (widget, row, 0, 0, &x, &y);
cairo_surface_set_device_offset (surface, -x, -y);
gtk_drag_set_icon_surface (context, surface);
gtk_widget_translate_coordinates(widget, row, 0, 0, &x, &y);
cairo_surface_set_device_offset(surface, -x, -y);
gtk_drag_set_icon_surface(context, surface);
cairo_destroy (cr);
cairo_surface_destroy (surface);
cairo_destroy(cr);
cairo_surface_destroy(surface);
g_object_set_data(G_OBJECT(gtk_widget_get_parent(row)), "drag-row", row);
gtk_style_context_add_class(gtk_widget_get_style_context(row), "drag-row");
@@ -116,14 +116,14 @@ static void sel_layer_element_drag_data_get(GtkWidget *widget, GdkDragContext *c
32, (const guchar *)&widget, sizeof(gpointer));
}
static GtkListBoxRow *layer_selector_get_last_row (GtkListBox *list)
static GtkListBoxRow *layer_selector_get_last_row(GtkListBox *list)
{
int i;
GtkListBoxRow *row;
GtkListBoxRow *tmp;
row = NULL;
for (i = 0; ; i++) {
GtkListBoxRow *tmp;
tmp = gtk_list_box_get_row_at_index(list, i);
if (tmp == NULL)
break;
@@ -133,15 +133,15 @@ static GtkListBoxRow *layer_selector_get_last_row (GtkListBox *list)
return row;
}
static GtkListBoxRow *layer_selector_get_row_before (GtkListBox *list, GtkListBoxRow *row)
static GtkListBoxRow *layer_selector_get_row_before(GtkListBox *list, GtkListBoxRow *row)
{
int pos;
pos = gtk_list_box_row_get_index (row);
return gtk_list_box_get_row_at_index (list, pos - 1);
pos = gtk_list_box_row_get_index(row);
return gtk_list_box_get_row_at_index(list, pos - 1);
}
static GtkListBoxRow *layer_selector_get_row_after (GtkListBox *list, GtkListBoxRow *row)
static GtkListBoxRow *layer_selector_get_row_after(GtkListBox *list, GtkListBoxRow *row)
{
int pos;
@@ -277,40 +277,40 @@ static void layer_selector_drag_leave(GtkWidget *widget, GdkDragContext *context
}
static const char *dnd_additional_css =
".row:not(:first-child) { "
" border-top: 1px solid alpha(gray,0.5); "
" border-bottom: 1px solid transparent; "
"}"
".row:first-child { "
" border-top: 1px solid transparent; "
" border-bottom: 1px solid transparent; "
"}"
".row:last-child { "
" border-top: 1px solid alpha(gray,0.5); "
" border-bottom: 1px solid alpha(gray,0.5); "
"}"
".row.drag-icon { "
" background: #282828; "
" border: 1px solid blue; "
"}"
".row.drag-row { "
" color: gray; "
" background: alpha(gray,0.2); "
"}"
".row.drag-row.drag-hover { "
" border-top: 1px solid #4e9a06; "
" border-bottom: 1px solid #4e9a06; "
"}"
".row.drag-hover image, "
".row.drag-hover label { "
" color: #4e9a06; "
"}"
".row.drag-hover-top {"
" border-top: 1px solid #4e9a06; "
"}"
".row.drag-hover-bottom {"
" border-bottom: 1px solid #4e9a06; "
"}";
".row:not(:first-child) { "
" border-top: 1px solid alpha(gray,0.5); "
" border-bottom: 1px solid transparent; "
"}"
".row:first-child { "
" border-top: 1px solid transparent; "
" border-bottom: 1px solid transparent; "
"}"
".row:last-child { "
" border-top: 1px solid alpha(gray,0.5); "
" border-bottom: 1px solid alpha(gray,0.5); "
"}"
".row.drag-icon { "
" background: #282828; "
" border: 1px solid blue; "
"}"
".row.drag-row { "
" color: gray; "
" background: alpha(gray,0.2); "
"}"
".row.drag-row.drag-hover { "
" border-top: 1px solid #4e9a06; "
" border-bottom: 1px solid #4e9a06; "
"}"
".row.drag-hover image, "
".row.drag-hover label { "
" color: #4e9a06; "
"}"
".row.drag-hover-top {"
" border-top: 1px solid #4e9a06; "
"}"
".row.drag-hover-bottom {"
" border-bottom: 1px solid #4e9a06; "
"}";
static void layer_selector_dispose(GObject *self)
{
@@ -349,7 +349,8 @@ static void layer_selector_class_init(LayerSelectorClass *klass)
static void layer_selector_setup_dnd(LayerSelector *self)
{
gtk_drag_dest_set(GTK_WIDGET(self->list_box), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, &self->dnd_target, 1, GDK_ACTION_MOVE);
gtk_drag_dest_set(GTK_WIDGET(self->list_box), GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP,
&self->dnd_target, 1, GDK_ACTION_MOVE);
g_signal_connect(self->list_box, "drag-data-received", G_CALLBACK(layer_selector_drag_data_received), NULL);
g_signal_connect(self->list_box, "drag-motion", G_CALLBACK(layer_selector_drag_motion), NULL);
g_signal_connect(self->list_box, "drag-leave", G_CALLBACK(layer_selector_drag_leave), NULL);
@@ -399,11 +400,11 @@ LayerSettings *layer_selector_export_rendered_layer_info(LayerSelector *selector
row_list = gtk_container_get_children(GTK_CONTAINER(selector->list_box));
for (i = 0,iterator = row_list; iterator != NULL; iterator = g_list_next(iterator), i++) {
for (i = 0, iterator = row_list; iterator != NULL; iterator = g_list_next(iterator), i++) {
le = LAYER_ELEMENT(iterator->data);
/* Get name from layer element. This must not be freed */
linfo.name =(char *)layer_element_get_name(le);
linfo.name = (char *)layer_element_get_name(le);
layer_element_get_color(le, &linfo.color);
linfo.render = (layer_element_get_export(le) ? 1 : 0);
@@ -425,9 +426,9 @@ static void layer_selector_clear_widgets(LayerSelector *self)
GList *temp;
list = gtk_container_get_children(GTK_CONTAINER(self->list_box));
for (temp = list; temp != NULL; temp = temp->next) {
for (temp = list; temp != NULL; temp = temp->next)
gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(temp->data));
}
/* Widgets are already destroyed when removed from box because they are only referenced inside the container */
g_list_free(list);
@@ -445,7 +446,8 @@ static void layer_selector_clear_widgets(LayerSelector *self)
* @param layer Layer number to check for
* @return TRUE if layer is present, else FALSE
*/
static gboolean layer_selector_check_if_layer_widget_exists(LayerSelector *self, int layer) {
static gboolean layer_selector_check_if_layer_widget_exists(LayerSelector *self, int layer)
{
GList *list;
GList *temp;
LayerElement *widget;
@@ -553,9 +555,8 @@ void layer_selector_generate_layer_widgets(LayerSelector *selector, GList *libs)
for (; libs != NULL; libs = libs->next) {
lib = (struct gds_library *)libs->data;
for (cell_list = lib->cells; cell_list != NULL; cell_list = cell_list->next) {
for (cell_list = lib->cells; cell_list != NULL; cell_list = cell_list->next)
layer_selector_analyze_cell_layers(selector, (struct gds_cell *)cell_list->data);
} /* For Cell List */
} /* For libs */
/* Sort the layers */
@@ -577,6 +578,7 @@ void layer_selector_generate_layer_widgets(LayerSelector *selector, GList *libs)
static LayerElement *layer_selector_find_layer_element_in_list(GList *el_list, int layer)
{
LayerElement *ret = NULL;
for (; el_list != NULL; el_list = el_list->next) {
if (layer_element_get_layer(LAYER_ELEMENT(el_list->data)) == layer) {
ret = LAYER_ELEMENT(el_list->data);
@@ -597,19 +599,18 @@ static LayerElement *layer_selector_find_layer_element_in_list(GList *el_list, i
* @param self LayerSelector instance
* @param file_name File name to load from
*/
static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, gchar *file_name)
static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, const gchar *file_name)
{
GFile *file;
GFileInputStream *stream;
GDataInputStream *dstream;
LayerElement *le;
char *name;
gboolean export;
int layer;
GdkRGBA color;
int result;
GList *rows;
GList *temp;
GList *layer_infos;
int status;
LayerSettings *layer_settings;
struct layer_info *linfo;
file = g_file_new_for_path(file_name);
stream = g_file_read(file, NULL, NULL);
@@ -624,31 +625,40 @@ static void layer_selector_load_layer_mapping_from_file(LayerSelector *self, gch
/* Reference and remove all rows from box */
for (temp = rows; temp != NULL; temp = temp->next) {
le = LAYER_ELEMENT(temp->data);
/* Referencing protets the widget from being deleted when removed */
/* Referencing protects the widget from being deleted when removed */
g_object_ref(G_OBJECT(le));
gtk_container_remove(GTK_CONTAINER(self->list_box), GTK_WIDGET(le));
}
while((result = mapping_parser_load_line(dstream, &export, &name, &layer, &color)) >= 0) {
/* skip broken line */
if (result == 1)
/* Load Layer settings. No need to check pointer, will be checked by load csv func. */
layer_settings = layer_settings_new();
status = layer_settings_load_from_csv(layer_settings, file_name);
if (status)
goto abort_layer_settings;
layer_infos = layer_settings_get_layer_info_list(layer_settings);
if (!layer_infos)
goto abort_layer_settings;
/* Loop over all layer infos read from the CSV file */
for (; layer_infos; layer_infos = g_list_next(layer_infos)) {
linfo = (struct layer_info *)layer_infos->data;
le = layer_selector_find_layer_element_in_list(rows, linfo->layer);
if (!le)
continue;
/* Add rows in the same order as in file */
if ((le = layer_selector_find_layer_element_in_list(rows, layer))) {
gtk_list_box_insert(self->list_box, GTK_WIDGET(le), -1);
layer_element_set_color(le, &color);
layer_element_set_export(le, export);
layer_element_set_name(le, name);
g_free(name);
/* Dereference and remove from list */
g_object_unref(G_OBJECT(le));
rows = g_list_remove(rows, le);
}
layer_element_set_name(le, linfo->name);
layer_element_set_export(le, (linfo->render ? TRUE : FALSE));
layer_element_set_color(le, &linfo->color);
gtk_container_add(GTK_CONTAINER(self->list_box), GTK_WIDGET(le));
rows = g_list_remove(rows, le);
}
abort_layer_settings:
/* Destroy layer settings. Not needed for adding remaining elements */
g_object_unref(layer_settings);
/* Add remaining elements */
for (temp = rows; temp != NULL; temp = temp->next) {
le = LAYER_ELEMENT(temp->data);
@@ -682,7 +692,8 @@ static void layer_selector_load_mapping_clicked(GtkWidget *button, gpointer user
sel = LAYER_SELECTOR(user_data);
dialog = gtk_file_chooser_dialog_new("Load Mapping File", GTK_WINDOW(sel->load_parent_window), GTK_FILE_CHOOSER_ACTION_OPEN,
dialog = gtk_file_chooser_dialog_new("Load Mapping File", GTK_WINDOW(sel->load_parent_window),
GTK_FILE_CHOOSER_ACTION_OPEN,
"Cancel", GTK_RESPONSE_CANCEL, "Load Mapping", GTK_RESPONSE_ACCEPT, NULL);
res = gtk_dialog_run(GTK_DIALOG(dialog));
if (res == GTK_RESPONSE_ACCEPT) {
@@ -702,29 +713,14 @@ static void layer_selector_load_mapping_clicked(GtkWidget *button, gpointer user
*/
static void layer_selector_save_layer_mapping_data(LayerSelector *self, const gchar *file_name)
{
FILE *file;
char workbuff[512];
GList *le_list;
GList *temp;
LayerSettings *layer_settings;
/* Overwrite existing file */
file = fopen((const char *)file_name, "w");
g_return_if_fail(LAYER_IS_SELECTOR(self));
g_return_if_fail(file_name);
le_list = gtk_container_get_children(GTK_CONTAINER(self->list_box));
/* File format is CSV: <Layer>,<target_pos>,<R>,<G>,<B>,<Alpha>,<Export?>,<Name> */
for (temp = le_list; temp != NULL; temp = temp->next) {
/* To be sure it is a valid string */
workbuff[0] = 0;
mapping_parser_gen_csv_line(LAYER_ELEMENT(temp->data), workbuff, sizeof(workbuff));
fwrite(workbuff, sizeof(char), strlen(workbuff), file);
}
g_list_free(le_list);
/* Save File */
fflush(file);
fclose(file);
/* Get layer settings. No need to check return value. to_csv func is safe */
layer_settings = layer_selector_export_rendered_layer_info(self);
(void)layer_settings_to_csv(layer_settings, file_name);
}
/**
@@ -742,7 +738,8 @@ static void layer_selector_save_mapping_clicked(GtkWidget *button, gpointer user
sel = LAYER_SELECTOR(user_data);
dialog = gtk_file_chooser_dialog_new("Save Mapping File", GTK_WINDOW(sel->save_parent_window), GTK_FILE_CHOOSER_ACTION_SAVE,
dialog = gtk_file_chooser_dialog_new("Save Mapping File", GTK_WINDOW(sel->save_parent_window),
GTK_FILE_CHOOSER_ACTION_SAVE,
"Cancel", GTK_RESPONSE_CANCEL, "Save Mapping", GTK_RESPONSE_ACCEPT, NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
@@ -809,9 +806,8 @@ void layer_selector_select_all_layers(LayerSelector *layer_selector, gboolean se
for (iter = le_list; iter != NULL; iter = g_list_next(iter)) {
le = LAYER_ELEMENT(iter->data);
if (LAYER_IS_ELEMENT(le)) {
if (LAYER_IS_ELEMENT(le))
layer_element_set_export(le, select);
}
}
g_list_free(le_list);
@@ -857,4 +853,49 @@ ret_free_le_list:
g_list_free(le_list);
}
void layer_selector_auto_name_layers(LayerSelector *layer_selector, gboolean overwrite)
{
GList *le_list;
GList *le_list_ptr;
LayerElement *le;
const char *old_layer_name;
GString *new_layer_name;
g_return_if_fail(LAYER_IS_SELECTOR(layer_selector));
new_layer_name = g_string_new_len(NULL, 10);
le_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
for (le_list_ptr = le_list; le_list_ptr != NULL; le_list_ptr = g_list_next(le_list_ptr)) {
le = LAYER_ELEMENT(le_list_ptr->data);
if (!le)
continue;
old_layer_name = layer_element_get_name(le);
/* Check if layer name is empty or may be overwritten */
if (!old_layer_name || *old_layer_name == '\0' || overwrite) {
g_string_printf(new_layer_name, "Layer %d", layer_element_get_layer(le));
layer_element_set_name(le, new_layer_name->str);
}
}
g_string_free(new_layer_name, TRUE);
g_list_free(le_list);
}
gboolean layer_selector_contains_elements(LayerSelector *layer_selector)
{
GList *layer_element_list;
/* Check objects */
g_return_val_if_fail(LAYER_IS_SELECTOR(layer_selector), FALSE);
g_return_val_if_fail(GTK_IS_LIST_BOX(layer_selector->list_box), FALSE);
/* Get a list of the child elements inside the list boy associated with this selector */
layer_element_list = gtk_container_get_children(GTK_CONTAINER(layer_selector->list_box));
/* Return TRUE if there is an element in the list, else return FALSE */
return (layer_element_list ? TRUE : FALSE);
}
/** @} */

View File

@@ -18,7 +18,7 @@
*/
/**
* @file layer-info.c
* @file layer-settings.c
* @brief Implementation of the LayerSettings class
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
@@ -77,9 +77,9 @@ static void layer_settings_class_init(LayerSettingsClass *klass)
* @brief Copy layer_info struct
*
* This function copies a layer info struct.
* Be aware, that it does not only copy the pointer to the
* layer name, but instead duplicates the string.
*
* @note Be aware, that it does not only copy the pointer to the
* layer name, but instead duplicates the string.
* @param info Info to copy
* @return new layer_info struct
*/
@@ -223,7 +223,7 @@ int layer_settings_to_csv(LayerSettings *settings, const char *path)
linfo = (struct layer_info *)info_iter->data;
layer_settings_gen_csv_line(string, linfo);
g_output_stream_write(w_fstream, string->str, sizeof(gchar), NULL, NULL);
g_output_stream_write(w_fstream, string->str, string->len * sizeof(gchar), NULL, NULL);
}
/* Delete string */
@@ -314,10 +314,14 @@ int layer_settings_load_from_csv(LayerSettings *settings, const char *path)
GInputStream *in_stream;
GDataInputStream *data_stream;
int parser_ret;
int stacked_pos;
struct layer_info linfo;
file = g_file_new_for_path(path);
in_stream = G_INPUT_STREAM(g_file_read(file, NULL, NULL));
g_return_val_if_fail(GDS_RENDER_IS_LAYER_SETTINGS(settings), -2);
if (!in_stream) {
ret = -1;
goto ret_destroy_file;
@@ -327,11 +331,14 @@ int layer_settings_load_from_csv(LayerSettings *settings, const char *path)
data_stream = g_data_input_stream_new(in_stream);
stacked_pos = 0;
while ((parser_ret = layer_settings_load_csv_line_from_stream(data_stream, &linfo)) >= 0) {
/* Line broken */
if (parser_ret == 1)
continue;
linfo.stacked_position = stacked_pos++;
layer_settings_append_layer_info(settings, &linfo);
/* Clear name to prevent memory leak */
if (linfo.name)

View File

@@ -1,144 +0,0 @@
/*
*
* GDSII-Converter
* Copyright (C) 2018 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file mapping-parser.c
* @brief Function to read a mapping file line and parse it.
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/**
* @addtogroup Mapping-Parser
* @{
*/
#include <gds-render/layer/mapping-parser.h>
int mapping_parser_load_line(GDataInputStream *stream, gboolean *export, char **name, int *layer, GdkRGBA *color)
{
int ret;
gsize len;
gchar *line;
GRegex *regex;
GMatchInfo *mi;
char *match;
if ((!export) || (!name) || (!layer) || (!color)) {
ret = 1;
goto ret_direct;
}
regex = g_regex_new("^(?<layer>[0-9]+),(?<r>[0-9\\.]+),(?<g>[0-9\\.]+),(?<b>[0-9\\.]+),(?<a>[0-9\\.]+),(?<export>[01]),(?<name>.*)$", 0, 0, NULL);
line = g_data_input_stream_read_line(stream, &len, NULL, NULL);
if (!line) {
ret = -1;
goto destroy_regex;
}
/* Match line in CSV */
g_regex_match(regex, line, 0, &mi);
if (g_match_info_matches(mi)) {
/* Line is valid */
match = g_match_info_fetch_named(mi, "layer");
*layer = (int)g_ascii_strtoll(match, NULL, 10);
g_free(match);
match = g_match_info_fetch_named(mi, "r");
color->red = g_ascii_strtod(match, NULL);
g_free(match);
match = g_match_info_fetch_named(mi, "g");
color->green = g_ascii_strtod(match, NULL);
g_free(match);
match = g_match_info_fetch_named(mi, "b");
color->blue = g_ascii_strtod(match, NULL);
g_free(match);
match = g_match_info_fetch_named(mi, "a");
color->alpha = g_ascii_strtod(match, NULL);
g_free(match);
match = g_match_info_fetch_named(mi, "export");
*export = ((!strcmp(match, "1")) ? TRUE : FALSE);
g_free(match);
match = g_match_info_fetch_named(mi, "name");
*name = match;
ret = 0;
} else {
/* Line is malformatted */
printf("Could not recognize line in CSV as valid entry: %s\n", line);
ret = 1;
}
g_match_info_free(mi);
g_free(line);
destroy_regex:
g_regex_unref(regex);
ret_direct:
return ret;
}
void mapping_parser_gen_csv_line(LayerElement *layer_element, char *line_buffer, size_t max_len)
{
int i;
GString *string;
gboolean export;
const gchar *name;
int layer;
GdkRGBA color;
string = g_string_new_len(NULL, max_len-1);
/* Extract values */
export = layer_element_get_export(layer_element);
name = (const gchar*)layer_element_get_name(layer_element);
layer = layer_element_get_layer(layer_element);
layer_element_get_color(layer_element, &color);
/* print values to line */
g_string_printf(string, "%d:%lf:%lf:%lf:%lf:%d:%s\n",
layer, color.red, color.green,
color.blue, color.alpha, (export == TRUE ? 1 : 0), name);
/* Fix broken locale settings */
for (i = 0; string->str[i]; i++) {
if (string->str[i] == ',')
string->str[i] = '.';
}
for (i = 0; string->str[i]; i++) {
if (string->str[i] == ':')
string->str[i] = ',';
}
if (string->len > (max_len-1)) {
printf("Layer Definition too long. Please shorten Layer Name!!\n");
line_buffer[0] = 0x0;
return;
}
/* copy max_len bytes of string */
strncpy(line_buffer, (char *)string->str, max_len-1);
line_buffer[max_len-1] = 0;
/* Completely remove string */
g_string_free(string, TRUE);
}
/** @} */

97
main.c
View File

@@ -26,6 +26,8 @@
#include <stdio.h>
#include <gtk/gtk.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <locale.h>
#include <gds-render/gds-render-gui.h>
#include <gds-render/command-line.h>
@@ -91,8 +93,8 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
(void)parameter;
GString *comment_text;
comment_text = g_string_new("gds-render is a tool fo rendering GDS2 layout files into vector graphics.");
g_string_append_printf(comment_text, "\n\n Full git commit: %s", _app_git_commit);
comment_text = g_string_new(_("gds-render is a free tool for rendering GDS2 layout files into vector graphics."));
g_string_append_printf(comment_text, _("\n\nFull git commit: %s"), _app_git_commit);
builder = gtk_builder_new_from_resource("/gui/about.glade");
dialog = GTK_DIALOG(gtk_builder_get_object(builder, "about-dialog"));
@@ -111,7 +113,7 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
/* Pixbuf is now owned by about dialog. Unref */
g_object_unref(logo_buf);
} else if (error) {
fprintf(stderr, "Logo could not be displayed: %s\n", error->message);
fprintf(stderr, _("Logo could not be displayed: %s\n"), error->message);
g_error_free(error);
}
@@ -125,15 +127,15 @@ static void app_about(GSimpleAction *action, GVariant *parameter, gpointer user_
* @brief Contains the application menu entries
*/
static const GActionEntry app_actions[] = {
{"quit", app_quit, NULL, NULL, NULL, {0}},
{"about", app_about, NULL, NULL, NULL, {0}}
{ "quit", app_quit, NULL, NULL, NULL, {0} },
{ "about", app_about, NULL, NULL, NULL, {0} },
};
/**
* @brief Called when a GUI main window is closed
*
* The GdsRenderGui object associated with the closed main window
* is removed from the list of open GUIs (\p user_data) and unreferenced.
* is removed from the list of open GUIs (\p user_data) and dereferenced.
*
* @param gui The GUI instance the closed main window belongs to
* @param user_data List of GUIs
@@ -156,7 +158,6 @@ static void gapp_activate(GApplication *app, gpointer user_data)
{
GtkWindow *main_window;
GdsRenderGui *gui;
struct application_data * const appdata = (struct application_data *)user_data;
gui = gds_render_gui_new();
@@ -183,8 +184,8 @@ static void gapp_activate(GApplication *app, gpointer user_data)
*/
static int start_gui(int argc, char **argv)
{
GtkApplication *gapp;
GString *application_domain;
int app_status;
static struct application_data appdata = {
.gui_list = NULL
@@ -193,21 +194,30 @@ static int start_gui(int argc, char **argv)
GMenu *m_quit;
GMenu *m_about;
gapp = gtk_application_new("de.shimatta.gds-render", G_APPLICATION_FLAGS_NONE);
/*
* Generate version dependent application id
* This allows running the application in different versions at the same time.
*/
application_domain = g_string_new(NULL);
g_string_printf(application_domain, "de.shimatta.gds_render_%s", _app_git_commit);
gapp = gtk_application_new(application_domain->str, G_APPLICATION_FLAGS_NONE);
g_string_free(application_domain, TRUE);
g_application_register(G_APPLICATION(gapp), NULL, NULL);
g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata);
if (g_application_get_is_remote(G_APPLICATION(gapp)) == TRUE) {
g_application_activate(G_APPLICATION(gapp));
printf("There is already an open instance. Will open second window in said instance.\n");
printf(_("There is already an open instance. Will open second window in that instance.\n"));
return 0;
}
menu = g_menu_new();
m_quit = g_menu_new();
m_about = g_menu_new();
g_menu_append(m_quit, "Quit", "app.quit");
g_menu_append(m_about, "About", "app.about");
g_menu_append(m_quit, _("Quit"), "app.quit");
g_menu_append(m_about, _("About"), "app.about");
g_menu_append_section(menu, NULL, G_MENU_MODEL(m_about));
g_menu_append_section(menu, NULL, G_MENU_MODEL(m_quit));
g_action_map_add_action_entries(G_ACTION_MAP(gapp), app_actions,
@@ -231,7 +241,7 @@ static int start_gui(int argc, char **argv)
*/
static void print_version(void)
{
printf("This is gds-render, version: %s\n\nFor a list of supported commands execute with --help option.\n",
printf(_("This is gds-render, version: %s\n\nFor a list of supported commands execute with --help option.\n"),
_app_version_string);
}
@@ -252,32 +262,46 @@ int main(int argc, char **argv)
gchar *cellname = NULL;
gchar **renderer_args = NULL;
gboolean version = FALSE, pdf_standalone = FALSE, pdf_layers = FALSE;
gchar *custom_library_path = NULL;
int scale = 1000;
int app_status = 0;
struct external_renderer_params so_render_params;
so_render_params.so_path = NULL;
so_render_params.cli_params = NULL;
bindtextdomain(GETTEXT_PACKAGE, LOCALEDATADIR "/locale");
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);
GOptionEntry entries[] = {
{"version", 'v', 0, G_OPTION_ARG_NONE, &version, "Print version", NULL},
{"renderer", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &renderer_args, "Renderer to use. Can be used multiple times.", "pdf|svg|tikz|ext"},
{"scale", 's', 0, G_OPTION_ARG_INT, &scale, "Divide output coordinates by <SCALE>", "<SCALE>" },
{"output-file", 'o', 0, G_OPTION_ARG_FILENAME_ARRAY, &output_paths, "Output file path. Can be used multiple times.", "PATH" },
{"mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, "Path for Layer Mapping File", "PATH" },
{"cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, "Cell to render", "NAME" },
{"tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, "Create standalone PDF", NULL },
{"tex-layers", 'l', 0, G_OPTION_ARG_NONE, &pdf_layers, "Create PDF Layers (OCG)", NULL },
{"custom-render-lib", 'P', 0, G_OPTION_ARG_FILENAME, &custom_library_path, "Path to a custom shared object, that implements the " EXTERNAL_LIBRARY_FUNCTION " function", "PATH"},
{NULL}
{"version", 'v', 0, G_OPTION_ARG_NONE, &version, _("Print version"), NULL},
{"renderer", 'r', 0, G_OPTION_ARG_STRING_ARRAY, &renderer_args,
_("Renderer to use. Can be used multiple times."), "pdf|svg|tikz|ext"},
{"scale", 's', 0, G_OPTION_ARG_INT, &scale, _("Divide output coordinates by <SCALE>"), "<SCALE>" },
{"output-file", 'o', 0, G_OPTION_ARG_FILENAME_ARRAY, &output_paths,
_("Output file path. Can be used multiple times."), "PATH" },
{"mapping", 'm', 0, G_OPTION_ARG_FILENAME, &mappingname, _("Path for Layer Mapping File"), "PATH" },
{"cell", 'c', 0, G_OPTION_ARG_STRING, &cellname, _("Cell to render"), "NAME" },
{"tex-standalone", 'a', 0, G_OPTION_ARG_NONE, &pdf_standalone, _("Create standalone TeX"), NULL },
{"tex-layers", 'l', 0, G_OPTION_ARG_NONE, &pdf_layers, _("Create PDF Layers (OCG)"), NULL },
{"custom-render-lib", 'P', 0, G_OPTION_ARG_FILENAME, &so_render_params.so_path,
_("Path to a custom shared object, that implements the necessary rendering functions"), "PATH"},
{"render-lib-params", 'W', 0, G_OPTION_ARG_STRING, &so_render_params.cli_params,
_("Argument string passed to render lib"), NULL},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
context = g_option_context_new(" FILE - Convert GDS file <FILE> to graphic");
context = g_option_context_new(_(" FILE - Convert GDS file <FILE> to graphic"));
g_option_context_add_main_entries(context, entries, NULL);
g_option_context_add_group(context, gtk_get_option_group(TRUE));
if (!g_option_context_parse(context, &argc, &argv, &error)) {
g_print("Option parsing failed: %s\n", error->message);
g_print(_("Option parsing failed: %s\n"), error->message);
exit(1);
}
g_option_context_free(context);
if (version) {
print_version();
goto ret_status;
@@ -285,29 +309,30 @@ int main(int argc, char **argv)
if (argc >= 2) {
if (scale < 1) {
printf("Scale < 1 not allowed. Setting to 1\n");
printf(_("Scale < 1 not allowed. Setting to 1\n"));
scale = 1;
}
/* Get gds name */
gds_name = argv[1];
/* Print out additional arguments as ignored */
for (i = 2; i < argc; i++) {
printf("Ignored argument: %s", argv[i]);
}
for (i = 2; i < argc; i++)
printf(_("Ignored argument: %s"), argv[i]);
app_status =
command_line_convert_gds(gds_name, cellname, renderer_args, output_paths, mappingname,
custom_library_path, pdf_standalone, pdf_layers, scale);
&so_render_params, pdf_standalone, pdf_layers, scale);
} else {
app_status = start_gui(argc, argv);
}
ret_status:
/* If necessary, free command line parameters */
/* If necessary, free command line parameters.
* This is only really necessary for automated mem-leak testing.
* Omitting these frees would be perfectly fine.
*/
if (output_paths)
g_strfreev(output_paths);
if (renderer_args)
@@ -316,8 +341,10 @@ ret_status:
g_free(mappingname);
if (cellname)
free(cellname);
if (custom_library_path)
free(custom_library_path);
if (so_render_params.so_path)
free(so_render_params.so_path);
if (so_render_params.cli_params)
g_free(so_render_params.cli_params);
return app_status;
}

View File

@@ -17,10 +17,10 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file cairo-output.c
* @brief Output renderer for Cairo PDF export
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
* @file cairo-renderer.c
* @brief Output renderer for Cairo PDF export
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/** @addtogroup Cairo-Renderer
* @{
@@ -31,6 +31,7 @@
#include <cairo.h>
#include <cairo-pdf.h>
#include <cairo-svg.h>
#include <glib/gi18n.h>
#include <gds-render/output-renderers/cairo-renderer.h>
#include <sys/wait.h>
@@ -121,7 +122,8 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
/* Render child cells */
for (instance_list = cell->child_cells; instance_list != NULL; instance_list = instance_list->next) {
cell_instance = (struct gds_cell_instance *)instance_list->data;
if ((temp_cell = cell_instance->cell_ref) != NULL) {
temp_cell = cell_instance->cell_ref;
if (temp_cell != NULL) {
apply_inherited_transform_to_all_layers(layers,
&cell_instance->origin,
cell_instance->magnification,
@@ -177,6 +179,7 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
cairo_stroke(cr);
break;
case GRAPHIC_BOX:
/* Expected fallthrough */
case GRAPHIC_POLYGON:
cairo_set_line_width(cr, 0.1/scale);
cairo_close_path(cr);
@@ -187,8 +190,39 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
} /* for gfx list */
}
/**
* @brief Read a line from a file descriptor
*
* In case of a broken pipe / closed writing end, it will terminate
*
* @param fd File descriptor to read from
* @param buff Buffer to write data in
* @param buff_size Buffer size
* @return length of read data
*/
static int read_line_from_fd(int fd, char *buff, size_t buff_size)
{
ssize_t cnt;
char c;
unsigned int buff_cnt = 0;
while ((cnt = read(fd, &c, 1)) == 1) {
if (buff_cnt < (buff_size-1)) {
buff[buff_cnt++] = c;
if (c == '\n')
break;
} else {
break;
}
}
buff[buff_cnt] = 0;
return (int)buff_cnt;
}
/**
* @brief Render \p cell to a PDF file specified by \p pdf_file
* @param renderer The current renderer this function is running from
* @param cell Toplevel cell to @ref Cairo-Renderer
* @param layer_infos List of layer information. Specifies color and layer stacking
* @param pdf_file PDF output file. Set to NULL if no PDF file has to be generated
@@ -196,8 +230,12 @@ static void render_cell(struct gds_cell *cell, struct cairo_layer *layers, doubl
* @param scale Scale the output image down by \p scale
* @return Error
*/
static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GList *layer_infos, const char *pdf_file,
const char *svg_file, double scale)
static int cairo_renderer_render_cell_to_vector_file(GdsOutputRenderer *renderer,
struct gds_cell *cell,
GList *layer_infos,
const char *pdf_file,
const char *svg_file,
double scale)
{
cairo_surface_t *pdf_surface = NULL, *svg_surface = NULL;
cairo_t *pdf_cr = NULL, *svg_cr = NULL;
@@ -209,28 +247,48 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
double rec_x0, rec_y0, rec_width, rec_height;
double xmin = INT32_MAX, xmax = INT32_MIN, ymin = INT32_MAX, ymax = INT32_MIN;
pid_t process_id;
int comm_pipe[2];
char receive_message[200];
if (pdf_file == NULL && svg_file == NULL) {
/* No output specified */
return -1;
}
/* Generate communication pipe for status updates */
if (pipe(comm_pipe) == -1)
return -2;
/* Fork to a new child process. This ensures the memory leaks (see issue #16) in Cairo don't
* brick everything.
*
* And by the way: This now bricks all Windows compatibility. Deal with it.
*/
/* Use fork for production code and -1 as value for debugging */
process_id = fork();
//process_id = -1;
if (process_id < 0) {
/* Well... shit... We have to run it in our process. */
/* This should not happen */
fprintf(stderr, _("Fatal error: Cairo Renderer: Could not spawn child process!"));
exit(-2);
} else if (process_id > 0) {
/* Woohoo... Successfully dumped the shitty code to an unknowing victim */
goto ret_parent;
}
/* We are now in a separate process just for rendering the output image.
* You may print a log message to the activity bar of the gui by writing a line
* teminated with '\n' to comm_pipe[1]. This will be handled by the parent process.
* Directly calling the update function
* gds_output_renderer_update_async_progress()
* does not have any effect because this is a separate process.
*/
/*
* Close stdin and (stdout and stderr may live on)
*/
close(0);
close(comm_pipe[0]);
layers = (struct cairo_layer *)calloc(MAX_LAYERS, sizeof(struct cairo_layer));
/* Clear layers */
@@ -260,7 +318,7 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
}
}
dprintf(comm_pipe[1], "Rendering layers\n");
render_cell(cell, layers, scale);
/* get size of image and top left coordinate */
@@ -268,7 +326,7 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
linfo = (struct layer_info *)info_list->data;
if (linfo->layer >= MAX_LAYERS) {
printf("Layer outside of Spec.\n");
printf(_("Layer number too high / outside of spec.\n"));
continue;
}
@@ -278,7 +336,7 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
/* Print size */
cairo_recording_surface_ink_extents(layers[linfo->layer].rec, &rec_x0, &rec_y0,
&rec_width, &rec_height);
printf("Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n",
dprintf(comm_pipe[1], _("Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n"),
linfo->layer,
(linfo->name && linfo->name[0] ? " (" : ""),
(linfo->name && linfo->name[0] ? linfo->name : ""),
@@ -297,7 +355,7 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
}
printf("Cell bounding box: (%lf | %lf) -- (%lf | %lf)\n", xmin, ymin, xmax, ymax);
/* printf("Cell bounding box: (%lf | %lf) -- (%lf | %lf)\n", xmin, ymin, xmax, ymax); */
if (pdf_file) {
pdf_surface = cairo_pdf_surface_create(pdf_file, xmax-xmin, ymax-ymin);
@@ -313,8 +371,10 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
for (info_list = layer_infos; info_list != NULL; info_list = g_list_next(info_list)) {
linfo = (struct layer_info *)info_list->data;
dprintf(comm_pipe[1], _("Exporting layer %d to file\n"), linfo->layer);
if (linfo->layer >= MAX_LAYERS) {
printf("Layer outside of Spec.\n");
printf(_("Layer outside of spec.\n"));
continue;
}
@@ -347,23 +407,35 @@ static int cairo_renderer_render_cell_to_vector_file(struct gds_cell *cell, GLis
ret_clear_layers:
for (i = 0; i < MAX_LAYERS; i++) {
lay = &layers[i];
if(lay->cr) {
if (lay->cr) {
cairo_destroy(lay->cr);
cairo_surface_destroy(lay->rec);
}
}
free(layers);
printf("Cairo export finished. It might still be buggy!\n");
printf(_("Cairo export finished. It might still be buggy!\n"));
/* If forked, suspend process */
if (process_id == 0)
exit(0);
/* Suspend child process */
exit(0);
/* Fork didn't work. Just return here */
return 0;
ret_parent:
close(comm_pipe[1]);
while (read_line_from_fd(comm_pipe[0], receive_message, sizeof(receive_message)) > 0) {
/* Strip \n from string and replace with ' ' */
for (i = 0; receive_message[i] != '\0'; i++) {
if (receive_message[i] == '\n')
receive_message[i] = ' ';
}
/* Update asyc progress*/
gds_output_renderer_update_async_progress(renderer, receive_message);
}
waitpid(process_id, NULL, 0);
close(comm_pipe[0]);
return 0;
}
@@ -400,8 +472,8 @@ static int cairo_renderer_render_output(GdsOutputRenderer *renderer,
else
pdf_file = output_file;
gds_output_renderer_update_gui_status_from_async(renderer, "Rendering Cairo Output...");
ret = cairo_renderer_render_cell_to_vector_file(cell, layer_infos, pdf_file, svg_file, scale);
gds_output_renderer_update_async_progress(renderer, _("Rendering Cairo Output..."));
ret = cairo_renderer_render_cell_to_vector_file(renderer, cell, layer_infos, pdf_file, svg_file, scale);
if (settings)
g_object_unref(settings);

View File

@@ -30,16 +30,23 @@
#include <dlfcn.h>
#include <stdio.h>
#include <sys/wait.h>
#include <glib/gi18n.h>
#include <gds-render/output-renderers/external-renderer.h>
#include <gds-render/version.h>
#define FORCE_FORK 0U /**< @brief if != 0, then forking is forced regardless of the shared object's settings */
struct _ExternalRenderer {
GdsOutputRenderer parent;
char *shared_object_path;
char *cli_param_string;
};
enum {
PROP_SO_PATH = 1, /**< @brief Shared object path property */
PROP_PARAM_STRING, /** @brief Shared object renderer parameter string from CLI */
N_PROPERTIES /**< @brief Used to get property count */
};
@@ -52,18 +59,23 @@ G_DEFINE_TYPE(ExternalRenderer, external_renderer, GDS_RENDER_TYPE_OUTPUT_RENDER
* @param output_file Destination file
* @param scale the scaling value to scale the output cell down by.
* @param so_path Path to shared object
* @param params Parameters passed to EXTERNAL_LIBRARY_INIT_FUNCTION
* @return 0 if successful
*/
static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *layer_info_list,
const char *output_file, double scale, const char *so_path)
const char *output_file, double scale, const char *so_path, const char *params)
{
int (*so_render_func)(struct gds_cell *, GList *, const char *, double) = NULL;
int (*so_init_func)(const char *, const char *) = NULL;
void *so_handle = NULL;
char *error_msg;
int forking_req;
int ret = 0;
pid_t fork_pid = 0;
int forked_status;
if (!so_path) {
fprintf(stderr, "Path to shared object not set!\n");
fprintf(stderr, _("Path to shared object not set!\n"));
return -3000;
}
@@ -74,25 +86,61 @@ static int external_renderer_render_cell(struct gds_cell *toplevel_cell, GList *
/* Load shared object */
so_handle = dlopen(so_path, RTLD_LAZY);
if (!so_handle) {
fprintf(stderr, "Could not load external library '%s'\nDetailed error is:\n%s\n", so_path, dlerror());
fprintf(stderr, _("Could not load external library '%s'\nDetailed error is:\n%s\n"), so_path, dlerror());
return -2000;
}
/* Load symbol from library */
so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double))dlsym(so_handle, EXTERNAL_LIBRARY_FUNCTION);
/* Load rendering symbol from library */
so_render_func = (int (*)(struct gds_cell *, GList *, const char *, double))
dlsym(so_handle, xstr(EXTERNAL_LIBRARY_RENDER_FUNCTION));
error_msg = dlerror();
if (error_msg != NULL) {
fprintf(stderr, "Rendering function not found in library:\n%s\n", error_msg);
fprintf(stderr, _("Rendering function not found in library:\n%s\n"), error_msg);
goto ret_close_so_handle;
}
/* Execute */
if (so_render_func) {
g_message("Calling external renderer.");
ret = so_render_func(toplevel_cell, layer_info_list, output_file, scale);
g_message("External renderer finished.");
/* Load the init function */
so_init_func = (int (*)(const char *, const char *))dlsym(so_handle, xstr(EXTERNAL_LIBRARY_INIT_FUNCTION));
error_msg = dlerror();
if (error_msg != NULL) {
fprintf(stderr, _("Init function not found in library:\n%s\n"), error_msg);
goto ret_close_so_handle;
}
/* Check if forking is requested */
if (dlsym(so_handle, xstr(EXTERNAL_LIBRARY_FORK_REQUEST)))
forking_req = 1;
else if (FORCE_FORK)
forking_req = 1;
else
forking_req = 0;
/* Execute */
g_message(_("Calling external renderer."));
if (forking_req)
fork_pid = fork();
if (fork_pid != 0)
goto end_forked;
ret = so_init_func(params, _app_version_string);
if (!ret)
ret = so_render_func(toplevel_cell, layer_info_list, output_file, scale);
/* If we are in a separate process, terminate here */
if (forking_req)
exit(ret);
/* The forked paths end here */
end_forked:
if (forking_req) {
waitpid(fork_pid, &forked_status, 0);
ret = WEXITSTATUS(forked_status);
}
g_message(_("External renderer finished."));
ret_close_so_handle:
dlclose(so_handle);
return ret;
@@ -115,7 +163,8 @@ static int external_renderer_render_output(GdsOutputRenderer *renderer,
if (settings)
layer_infos = layer_settings_get_layer_info_list(settings);
ret = external_renderer_render_cell(cell, layer_infos, output_file, scale, ext_renderer->shared_object_path);
ret = external_renderer_render_cell(cell, layer_infos, output_file, scale, ext_renderer->shared_object_path,
ext_renderer->cli_param_string);
if (settings)
g_object_unref(settings);
@@ -132,8 +181,11 @@ static void external_renderer_get_property(GObject *obj, guint property_id, GVal
case PROP_SO_PATH:
g_value_set_string(value, self->shared_object_path);
break;
case PROP_PARAM_STRING:
g_value_set_string(value, self->cli_param_string);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, property_id, pspec);
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
break;
}
}
@@ -150,6 +202,11 @@ static void external_renderer_set_property(GObject *obj, guint property_id, cons
g_free(self->shared_object_path);
self->shared_object_path = g_value_dup_string(value);
break;
case PROP_PARAM_STRING:
if (self->cli_param_string)
g_free(self->cli_param_string);
self->cli_param_string = g_value_dup_string(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, property_id, pspec);
break;
@@ -158,7 +215,9 @@ static void external_renderer_set_property(GObject *obj, guint property_id, cons
static void external_renderer_dispose(GObject *self_obj)
{
ExternalRenderer *self = GDS_RENDER_EXTERNAL_RENDERER(self_obj);
ExternalRenderer *self;
self = GDS_RENDER_EXTERNAL_RENDERER(self_obj);
if (self->shared_object_path) {
g_free(self->shared_object_path);
@@ -188,9 +247,15 @@ static void external_renderer_class_init(ExternalRendererClass *klass)
/* Setup properties */
external_renderer_properties[PROP_SO_PATH] =
g_param_spec_string("shared-object-path",
"Shared object file path",
"Path to the shared object to search rendering function in.",
g_param_spec_string(N_("shared-object-path"),
N_("Shared object file path"),
N_("Path to the shared object to search rendering function in."),
NULL,
G_PARAM_READWRITE);
external_renderer_properties[PROP_PARAM_STRING] =
g_param_spec_string(N_("param-string"),
N_("Shared object renderer parameter string"),
N_("Command line arguments passed to the external shared object renderer"),
NULL,
G_PARAM_READWRITE);
g_object_class_install_properties(oclass, N_PROPERTIES, external_renderer_properties);
@@ -199,6 +264,7 @@ static void external_renderer_class_init(ExternalRendererClass *klass)
static void external_renderer_init(ExternalRenderer *self)
{
self->shared_object_path = NULL;
self->cli_param_string = NULL;
}
ExternalRenderer *external_renderer_new()
@@ -206,9 +272,10 @@ ExternalRenderer *external_renderer_new()
return g_object_new(GDS_RENDER_TYPE_EXTERNAL_RENDERER, NULL);
}
ExternalRenderer *external_renderer_new_with_so(const char *so_path)
ExternalRenderer *external_renderer_new_with_so_and_param(const char *so_path, const char *param_string)
{
return g_object_new(GDS_RENDER_TYPE_EXTERNAL_RENDERER, "shared-object-path", so_path, NULL);
return g_object_new(GDS_RENDER_TYPE_EXTERNAL_RENDERER, N_("shared-object-path"), so_path,
N_("param-string"), param_string, NULL);
}
/** @} */

View File

@@ -18,16 +18,17 @@
*/
/**
* @file gds-output-renderer.c
* @brief Base GObject class for output renderers
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
* @file gds-output-renderer.c
* @brief Base GObject class for output renderers
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
/** @addtogroup GdsOutputRenderer
* @{
*/
#include <gds-render/output-renderers/gds-output-renderer.h>
#include <glib/gi18n.h>
struct renderer_params {
struct gds_cell *cell;
@@ -70,7 +71,7 @@ static int gds_output_renderer_render_dummy(GdsOutputRenderer *renderer,
(void)cell;
(void)scale;
g_warning("Output renderer does not define a render_output function!");
g_warning(_("Output renderer does not define a render_output function!"));
return 0;
}
@@ -99,6 +100,11 @@ static void gds_output_renderer_dispose(GObject *self_obj)
if (priv->output_file)
g_free(priv->output_file);
if (priv->idle_function_parameters.status_message) {
g_free(priv->idle_function_parameters.status_message);
priv->idle_function_parameters.status_message = NULL;
}
g_clear_object(&priv->layer_settings);
/* Chain up to parent class */
@@ -168,17 +174,17 @@ static void gds_output_renderer_class_init(GdsOutputRendererClass *klass)
/* Setup properties */
gds_output_renderer_properties[PROP_OUTPUT_FILE] =
g_param_spec_string("output-file", "output file", "Output file for renderer",
g_param_spec_string(N_("output-file"), N_("output file"), N_("Output file for renderer"),
NULL, G_PARAM_READWRITE);
gds_output_renderer_properties[PROP_LAYER_SETTINGS] =
g_param_spec_object("layer-settings", "Layer Settings object",
"Object containing the layer rendering information",
g_param_spec_object(N_("layer-settings"), N_("Layer Settings object"),
N_("Object containing the layer rendering information"),
GDS_RENDER_TYPE_LAYER_SETTINGS, G_PARAM_READWRITE);
g_object_class_install_properties(oclass, N_PROPERTIES, gds_output_renderer_properties);
/* Setup output signals */
gds_output_renderer_signals[ASYNC_FINISHED] =
g_signal_newv("async-finished", GDS_RENDER_TYPE_OUTPUT_RENDERER,
g_signal_newv(N_("async-finished"), GDS_RENDER_TYPE_OUTPUT_RENDERER,
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
NULL,
NULL,
@@ -188,7 +194,7 @@ static void gds_output_renderer_class_init(GdsOutputRendererClass *klass)
0,
NULL);
gds_output_renderer_signals[ASYNC_PROGRESS_CHANGED] =
g_signal_newv("progress-changed", GDS_RENDER_TYPE_OUTPUT_RENDERER,
g_signal_newv(N_("progress-changed"), GDS_RENDER_TYPE_OUTPUT_RENDERER,
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
NULL,
NULL,
@@ -213,8 +219,6 @@ void gds_output_renderer_init(GdsOutputRenderer *self)
priv->idle_function_parameters.status_message = NULL;
g_mutex_init(&priv->settings_lock);
g_mutex_init(&priv->idle_function_parameters.message_lock);
return;
}
GdsOutputRenderer *gds_output_renderer_new()
@@ -225,8 +229,8 @@ GdsOutputRenderer *gds_output_renderer_new()
GdsOutputRenderer *gds_output_renderer_new_with_props(const char *output_file, LayerSettings *layer_settings)
{
return GDS_RENDER_OUTPUT_RENDERER(g_object_new(GDS_RENDER_TYPE_OUTPUT_RENDERER,
"layer-settings", layer_settings,
"output-file", output_file,
N_("layer-settings"), layer_settings,
N_("output-file"), output_file,
NULL));
}
@@ -237,14 +241,14 @@ void gds_output_renderer_set_output_file(GdsOutputRenderer *renderer, const gcha
/* Check if the filename is actually filled */
if (!file_name || !file_name[0])
return;
g_object_set(renderer, "output-file", file_name, NULL);
g_object_set(renderer, N_("output-file"), file_name, NULL);
}
const char *gds_output_renderer_get_output_file(GdsOutputRenderer *renderer)
{
const char *file = NULL;
g_object_get(renderer, "output-file", &file, NULL);
g_object_get(renderer, N_("output-file"), &file, NULL);
return file;
}
@@ -259,9 +263,7 @@ LayerSettings *gds_output_renderer_get_and_ref_layer_settings(GdsOutputRenderer
g_mutex_lock(&priv->settings_lock);
/* This function seems to already reference the LayerSettings object */
g_object_get(renderer, "layer-settings", &ret, NULL);
/* Reference it, so it is not cleared by another thread overwriting the property */
//g_object_ref(ret);
g_object_get(renderer, N_("layer-settings"), &ret, NULL);
/* It is now safe to clear the lock */
g_mutex_unlock(&priv->settings_lock);
@@ -273,7 +275,7 @@ void gds_output_renderer_set_layer_settings(GdsOutputRenderer *renderer, LayerSe
{
g_return_if_fail(GDS_RENDER_IS_LAYER_SETTINGS(settings));
g_object_set(renderer, "layer-settings", settings, NULL);
g_object_set(renderer, N_("layer-settings"), settings, NULL);
}
int gds_output_renderer_render_output(GdsOutputRenderer *renderer, struct gds_cell *cell, double scale)
@@ -283,28 +285,28 @@ int gds_output_renderer_render_output(GdsOutputRenderer *renderer, struct gds_ce
GdsOutputRendererPrivate *priv = gds_output_renderer_get_instance_private(renderer);
if (GDS_RENDER_IS_OUTPUT_RENDERER(renderer) == FALSE) {
g_error("Output Renderer not valid.");
g_error(_("Output Renderer not valid."));
return GDS_OUTPUT_RENDERER_GEN_ERR;
}
if (!priv->output_file || !priv->output_file[0]) {
g_error("No/invalid output file set.");
g_error(_("No/invalid output file set."));
return GDS_OUTPUT_RENDERER_GEN_ERR;
}
if (!priv->layer_settings) {
g_error("No layer specification supplied.");
g_error(_("No layer specification supplied."));
return GDS_OUTPUT_RENDERER_GEN_ERR;
}
if (!cell) {
g_error("Output renderer called without cell to render.");
g_error(_("Output renderer called without cell to render."));
return GDS_OUTPUT_RENDERER_PARAM_ERR;
}
klass = GDS_RENDER_OUTPUT_RENDERER_GET_CLASS(renderer);
if (klass->render_output == NULL) {
g_critical("Output Renderer: Rendering function broken. This is a bug.");
g_critical(_("Output Renderer: Rendering function broken. This is a bug."));
return GDS_OUTPUT_RENDERER_GEN_ERR;
}
@@ -330,7 +332,7 @@ static void gds_output_renderer_async_wrapper(GTask *task,
ret = -1000;
goto ret_from_task;
}
if(!priv->mutex_init_status) {
if (!priv->mutex_init_status) {
ret = -1001;
goto ret_from_task;
}
@@ -365,12 +367,14 @@ int gds_output_renderer_render_output_async(GdsOutputRenderer *renderer, struct
priv = gds_output_renderer_get_instance_private(renderer);
if (priv->task) {
g_warning("renderer already started asynchronously");
g_warning(_("Renderer already started asynchronously"));
return -2000;
}
priv->task = g_task_new(renderer, NULL, gds_output_renderer_async_finished, NULL);
g_task_set_name(priv->task, "Rendering Thread");
/* This function is not available on current debian distros. */
/* g_task_set_name(priv->task, "Rendering Thread"); */
g_mutex_lock(&priv->settings_lock);
priv->async_params.cell = cell;
@@ -415,7 +419,7 @@ static gboolean idle_event_processor_callback(gpointer user_data)
return FALSE;
}
void gds_output_renderer_update_gui_status_from_async(GdsOutputRenderer *renderer, const char *status)
void gds_output_renderer_update_async_progress(GdsOutputRenderer *renderer, const char *status)
{
GSource *idle_event_processor;
GdsOutputRendererPrivate *priv;

View File

@@ -18,7 +18,7 @@
*/
/**
* @file latex-output.c
* @file latex-renderer.c
* @brief LaTeX Output Renderer
* @author Mario Hüttel <mario.huettel@gmx.net>
*/
@@ -27,6 +27,8 @@
#include <stdio.h>
#include <gds-render/output-renderers/latex-renderer.h>
#include <gdk/gdk.h>
#include <glib/gi18n.h>
/**
* @addtogroup LaTeX-Renderer
* @{
@@ -35,7 +37,7 @@
/**
* @brief Struct representing the LaTeX-Renderer object.
*
* This struct holds the LaTeX renderer internal data. It is only used inside the @ref LatexRenderer class.
* This struct holds the LaTeX renderer internal data. It is only used inside the @ref LaTeX-Renderer class.
*/
struct _LatexRenderer {
GdsOutputRenderer parent;
@@ -140,7 +142,8 @@ static gboolean write_layer_env(FILE *tex_file, GdkRGBA *color, int layer, GList
color->red = inf->color.red;
color->green = inf->color.green;
color->blue = inf->color.blue;
g_string_printf(buffer, "\\begin{pgfonlayer}{l%d}\n\\ifcreatepdflayers\n\\begin{scope}[ocg={ref=%d, status=visible,name={%s}}]\n\\fi\n",
g_string_printf(buffer,
"\\begin{pgfonlayer}{l%d}\n\\ifcreatepdflayers\n\\begin{scope}[ocg={ref=%d, status=visible,name={%s}}]\n\\fi\n",
layer, layer, inf->name);
WRITEOUT_BUFFER(buffer);
return TRUE;
@@ -167,21 +170,26 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
struct gds_graphics *gfx;
struct gds_point *pt;
GdkRGBA color;
static const char *line_caps[] = {"butt", "round", "rect"};
static const char * const line_caps[] = {"butt", "round", "rect"};
for (temp = graphics; temp != NULL; temp = temp->next) {
gfx = (struct gds_graphics *)temp->data;
if (write_layer_env(tex_file, &color, (int)gfx->layer, linfo, buffer) == TRUE) {
/* Layer is defined => create graphics */
if (gfx->gfx_type == GRAPHIC_POLYGON || gfx->gfx_type == GRAPHIC_BOX ) {
g_string_printf(buffer, "\\draw[line width=0.00001 pt, draw={c%d}, fill={c%d}, fill opacity={%lf}] ",
if (gfx->gfx_type == GRAPHIC_POLYGON || gfx->gfx_type == GRAPHIC_BOX) {
g_string_printf(buffer,
"\\draw[line width=0.00001 pt, draw={c%d}, fill={c%d}, fill opacity={%lf}] ",
gfx->layer, gfx->layer, color.alpha);
WRITEOUT_BUFFER(buffer);
/* Append vertices */
for (temp_vertex = gfx->vertices; temp_vertex != NULL; temp_vertex = temp_vertex->next) {
for (temp_vertex = gfx->vertices;
temp_vertex != NULL;
temp_vertex = temp_vertex->next) {
pt = (struct gds_point *)temp_vertex->data;
g_string_printf(buffer, "(%lf pt, %lf pt) -- ", ((double)pt->x)/scale, ((double)pt->y)/scale);
g_string_printf(buffer, "(%lf pt, %lf pt) -- ",
((double)pt->x)/scale,
((double)pt->y)/scale);
WRITEOUT_BUFFER(buffer);
}
g_string_printf(buffer, "cycle;\n");
@@ -204,7 +212,9 @@ static void generate_graphics(FILE *tex_file, GList *graphics, GList *linfo, GSt
WRITEOUT_BUFFER(buffer);
/* Append vertices */
for (temp_vertex = gfx->vertices; temp_vertex != NULL; temp_vertex = temp_vertex->next) {
for (temp_vertex = gfx->vertices;
temp_vertex != NULL;
temp_vertex = temp_vertex->next) {
pt = (struct gds_point *)temp_vertex->data;
g_string_printf(buffer, "(%lf pt, %lf pt)%s",
((double)pt->x)/scale,
@@ -240,8 +250,8 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
struct gds_cell_instance *inst;
status = g_string_new(NULL);
g_string_printf(status, "Generating cell %s", cell->name);
gds_output_renderer_update_gui_status_from_async(renderer, status->str);
g_string_printf(status, _("Generating cell %s"), cell->name);
gds_output_renderer_update_async_progress(renderer, status->str);
g_string_free(status, TRUE);
/* Draw polygons of current cell */
@@ -257,13 +267,14 @@ static void render_cell(struct gds_cell *cell, GList *layer_infos, FILE *tex_fil
/* generate translation scope */
g_string_printf(buffer, "\\begin{scope}[shift={(%lf pt,%lf pt)}]\n",
((double)inst->origin.x)/scale,((double)inst->origin.y)/scale);
((double)inst->origin.x) / scale, ((double)inst->origin.y) / scale);
WRITEOUT_BUFFER(buffer);
g_string_printf(buffer, "\\begin{scope}[rotate=%lf]\n", inst->angle);
WRITEOUT_BUFFER(buffer);
g_string_printf(buffer, "\\begin{scope}[yscale=%lf, xscale=%lf]\n", (inst->flipped ? -1*inst->magnification : inst->magnification),
g_string_printf(buffer, "\\begin{scope}[yscale=%lf, xscale=%lf]\n",
(inst->flipped ? -1*inst->magnification : inst->magnification),
inst->magnification);
WRITEOUT_BUFFER(buffer);
@@ -302,7 +313,8 @@ static int latex_render_cell_to_code(struct gds_cell *cell, GList *layer_infos,
WRITEOUT_BUFFER(working_line);
g_string_printf(working_line, "\\iftestmode\n");
WRITEOUT_BUFFER(working_line);
g_string_printf(working_line, "\\documentclass[tikz]{standalone}\n\\usepackage{xcolor}\n\\usetikzlibrary{ocgx}\n\\begin{document}\n");
g_string_printf(working_line,
"\\documentclass[tikz]{standalone}\n\\usepackage{xcolor}\n\\usetikzlibrary{ocgx}\n\\begin{document}\n");
WRITEOUT_BUFFER(working_line);
g_string_printf(working_line, "\\fi\n");
WRITEOUT_BUFFER(working_line);
@@ -358,12 +370,11 @@ static int latex_renderer_render_output(GdsOutputRenderer *renderer,
l_renderer->pdf_layers, l_renderer->tex_standalone, renderer);
fclose(tex_file);
} else {
g_error("Could not open LaTeX output file");
g_error(_("Could not open LaTeX output file"));
}
if (settings) {
if (settings)
g_object_unref(settings);
}
return ret;
}
@@ -424,14 +435,14 @@ static void latex_renderer_class_init(LatexRendererClass *klass)
latex_renderer_properties[PROP_STANDALONE] =
g_param_spec_boolean("standalone",
"Standalone TeX file",
"Generate a standalone LaTeX file.",
N_("Standalone TeX file"),
N_("Generate a standalone LaTeX file."),
FALSE,
G_PARAM_READWRITE);
latex_renderer_properties[PROP_PDF_LAYERS] =
g_param_spec_boolean("pdf-layers",
"PDF OCR layers",
"Generate OCR layers",
N_("PDF OCR layers"),
N_("Generate OCR layers"),
FALSE,
G_PARAM_READWRITE);

2
plugins/CMakeLists.txt Normal file
View File

@@ -0,0 +1,2 @@
add_subdirectory(plugin-example)
add_custom_target(plugins DEPENDS pluginexample)

View File

@@ -0,0 +1,14 @@
project(pluginexample)
cmake_minimum_required(VERSION 2.8)
find_package(PkgConfig REQUIRED)
pkg_search_module(PYTHON REQUIRED python3)
aux_source_directory(src SOURCES)
include_directories(${PYTHON_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/include)
link_libraries(${PYTHON_LDFLAGS} version)
add_library(${PROJECT_NAME} SHARED EXCLUDE_FROM_ALL ${SOURCES})
add_dependencies(${PROJECT_NAME} version)
set_target_properties(${PROJECT_NAME} PROPERTIES C_VISIBILITY_PRESET hidden)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_VISIBILITY_PRESET hidden)

View File

@@ -0,0 +1,49 @@
/*
* GDSII-Converter example plugin
* Copyright (C) 2019 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of GDSII-Converter.
*
* GDSII-Converter is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* GDSII-Converter is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @defgroup example-plugin Example Plugin for External Renderer
* @ingroup plugins
* This is a template / example for an external renderer plugin
* @addtogroup example-plugin
* @{
*/
#include <stdio.h>
#include <glib.h>
#include <gds-render/gds-utils/gds-types.h>
#include <gds-render/output-renderers/external-renderer-interfaces.h>
int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_RENDER_FUNCTION)(struct gds_cell *toplevel, GList *layer_info_list, const char *output_file_name, double scale)
{
if (!toplevel)
return -1000;
printf("Rendering %s\n", toplevel->name);
return 0;
}
int EXPORTED_FUNC_DECL(EXTERNAL_LIBRARY_INIT_FUNCTION)(const char *params, const char *version)
{
printf("Init with params: %s\ngds-render version: %s\n", params, version);
return 0;
}
/** @} */

View File

@@ -2,6 +2,11 @@
<!-- Generated with glade 3.22.1 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkImage" id="auto-name-img">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-edit</property>
</object>
<object class="GtkImage" id="color-img">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -15,6 +20,7 @@
<object class="GtkImage" id="save-mapping-img">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Save the current layer configuration to CSV</property>
<property name="stock">gtk-save-as</property>
</object>
<object class="GtkImage" id="select-all-img">
@@ -41,7 +47,7 @@
<property name="name">header</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="title" translatable="yes">GDS Renderer</property>
<property name="title" translatable="yes">GDS-Render</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkButton" id="button-load-gds">
@@ -49,6 +55,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Open GDS2 Database</property>
<property name="use_stock">True</property>
<property name="always_show_image">True</property>
<style>
@@ -63,6 +70,7 @@
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Load the current layer configuration from CSV</property>
<property name="image">load-mapping-img</property>
<property name="always_show_image">True</property>
<style>
@@ -98,6 +106,7 @@
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Convert selected cell</property>
<property name="use_stock">True</property>
<property name="always_show_image">True</property>
<style>
@@ -183,6 +192,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Sort layers ascending</property>
<property name="image">sort-up-img</property>
<property name="always_show_image">True</property>
</object>
@@ -197,6 +207,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Sort layers descending</property>
<property name="image">sort-down-img</property>
<property name="always_show_image">True</property>
</object>
@@ -211,6 +222,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Automatically color layers</property>
<property name="image">color-img</property>
<property name="always_show_image">True</property>
</object>
@@ -225,6 +237,7 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Select all layers for export</property>
<property name="image">select-all-img</property>
<property name="always_show_image">True</property>
</object>
@@ -234,6 +247,21 @@
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button-auto-name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Automatically name layers</property>
<property name="image">auto-name-img</property>
<property name="always_show_image">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
@@ -245,6 +273,7 @@
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="margin_top">1</property>
<property name="hscrollbar_policy">never</property>
<property name="shadow_type">in</property>
<child>

41
test/CMakeLists.txt Normal file
View File

@@ -0,0 +1,41 @@
project(gds-render-test)
add_custom_target(test "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}" "-r compact" "-s" DEPENDS ${PROJECT_NAME})
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColorReset "${Esc}[m")
set(ColorBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
cmake_minimum_required(VERSION 2.8)
find_package(PkgConfig REQUIRED)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/catch-framework")
aux_source_directory("geometric" GEOMETRIC_TEST_SOURCES)
set(TEST_SOURCES
${GEOMETRIC_TEST_SOURCES}
)
set(DUT_SOURCES
"../geometric/vector-operations.c"
)
add_executable(${PROJECT_NAME} EXCLUDE_FROM_ALL "test-main.cpp" ${TEST_SOURCES} ${DUT_SOURCES})
target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m version ${CMAKE_DL_LIBS})

17618
test/catch-framework/catch.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,160 @@
#include <catch.hpp>
#include <limits>
extern "C" {
#include <gds-render/geometric/vector-operations.h>
}
TEST_CASE("geometric/vector-operations/vector_2d_add", "[GEOMETRIC]")
{
struct vector_2d res;
struct vector_2d a;
struct vector_2d b;
a.x = 1;
a.y = 2;
b.x = 2;
b.y = 6;
vector_2d_add(&res, &a, &b);
REQUIRE(res.x == Approx(a.x + b.x));
REQUIRE(res.y == Approx(a.y + b.y));
}
TEST_CASE("geometric/vector-operations/vector_2d_calculate_angle_between", "[GEOMETRIC]")
{
double angle;
struct vector_2d a;
struct vector_2d b;
a.x = 1;
a.y = 0;
b.x = 0;
b.y = 1;
angle = vector_2d_calculate_angle_between(&a, &a);
REQUIRE(angle == Approx(0.0));
angle = vector_2d_calculate_angle_between(&a, &b);
REQUIRE(angle == Approx(90.0 / 180.0 * M_PI));
}
TEST_CASE("geometric/vector-operations/vector_2d_subtract", "[GEOMETRIC]")
{
struct vector_2d res;
struct vector_2d a;
struct vector_2d b;
a.x = 1;
a.y = 2;
b.x = 2;
b.y = 6;
vector_2d_subtract(&res, &a, &b);
REQUIRE(res.x == Approx(a.x - b.x));
REQUIRE(res.y == Approx(a.y - b.y));
}
TEST_CASE("geometric/vector-operations/vector_2d_abs", "[GEOMETRIC]")
{
struct vector_2d c;
struct vector_2d a;
struct vector_2d b;
double a_len, b_len, c_len;
a.x = 1;
a.y = 0;
b.x = 0;
b.y = 2;
c.x = 3;
c.y = 4;
a_len = vector_2d_abs(&a);
b_len = vector_2d_abs(&b);
c_len = vector_2d_abs(&c);
REQUIRE(a_len == Approx(1.0));
REQUIRE(b_len == Approx(2.0));
REQUIRE(c_len == Approx(5.0));
}
TEST_CASE("geometric/vector-operations/vector_2d_scalar_multipy", "[GEOMETRIC]")
{
struct vector_2d c;
struct vector_2d a;
struct vector_2d b;
double mult;
a.x = 1;
a.y = 0;
b.x = 0;
b.y = 2;
mult = vector_2d_scalar_multipy(&a, &b);
REQUIRE(mult == Approx(0.0));
a.x = 1;
a.y = 1;
b.x = 1;
b.y = 1;
mult = vector_2d_scalar_multipy(&a, &b);
REQUIRE(mult == Approx(2.0));
}
TEST_CASE("geometric/vector-operations/vector_2d_normalize", "[GEOMETRIC]")
{
struct vector_2d a;
a.x = 1;
a.y = 0;
vector_2d_normalize(&a);
REQUIRE(a.x == Approx(1.0));
REQUIRE(a.y == Approx(0.0));
a.x = 1;
a.y = -1;
vector_2d_normalize(&a);
REQUIRE(a.x == Approx(1.0/sqrt(2)));
REQUIRE(a.y == Approx(-1.0/sqrt(2)));
}
TEST_CASE("geometric/vector-operations/vector_2d_rotate", "[GEOMETRIC]")
{
struct vector_2d a;
a.x = 1;
a.y = 0;
vector_2d_rotate(&a, M_PI/2);
REQUIRE(a.x == Approx(0.0).scale(0.001));
REQUIRE(a.y == Approx(1.0));
a.x = 0;
a.y = 1;
vector_2d_rotate(&a, -M_PI/2);
vector_2d_rotate(&a, M_PI);
REQUIRE(a.x == Approx(-1.0));
REQUIRE(a.y == Approx(0.0).scale(0.001));
}
TEST_CASE("geometric/vector-operations/vector_2d_scale", "[GEOMETRIC]")
{
struct vector_2d a;
a.x = 1;
a.y = 0;
vector_2d_scale(&a, 2.0);
REQUIRE(a.x == Approx(2.0));
REQUIRE(a.y == Approx(0.0));
a.x = 1;
a.y = -3;
vector_2d_scale(&a, 0.5);
REQUIRE(a.x == Approx(0.5));
REQUIRE(a.y == Approx(-1.5));
}

2
test/test-main.cpp Normal file
View File

@@ -0,0 +1,2 @@
#define CATCH_CONFIG_MAIN
#include "catch-framework/catch.hpp"

1
translations/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.mo

View File

@@ -0,0 +1,16 @@
add_custom_target(translations
DEPENDS
"${PROJECT_BINARY_DIR}/translations/output/"
)
add_custom_command(DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/pot/po/*"
OUTPUT
"${PROJECT_BINARY_DIR}/translations/output/"
COMMAND
COMMAND ./generate-mo.sh "${PROJECT_BINARY_DIR}/translations/output"
WORKING_DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR}
COMMENT
"Generating translation locales"
)

24
translations/generate-mo.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && pwd )"
cd "$DIR"
if [ -z $1 ]; then
echo "Must supply an output name"
exit -2
fi
for langdir in `find ./pot/po -mindepth 1 -maxdepth 1 -type d`; do
lang=`basename "$langdir"`
dest="$1/locale/$lang/LC_MESSAGES"
mkdir -p "$dest"
pofiles=`find "$langdir" -name "*.po" | tr '\n' ' '`
comb=`msgcat $pofiles`
echo "$comb" | msgfmt --output-file="$dest/gds-render.mo" -
done

View File

@@ -0,0 +1,39 @@
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && pwd )"
cd "$DIR"
files=`find ../ -name "*.c"`
mkdir -p "pot"
# C Files
pot="pot/gds-render.pot"
for file in $files; do
echo "Parsing C file $file"
# pot="pot/"$(echo "${file#*/}" | sed -e "s/\//_/g")
# pot="${pot%.c}.pot"
if [[ -f "$pot" ]]; then
xgettext --package-name="gds-render" --join-existing --keyword=_ --language=C --add-comments --sort-output -o "$pot" "$file"
else
xgettext --package-name="gds-render" --keyword=_ --language=C --add-comments --sort-output -o "$pot" "$file"
fi
done
# Glade files
glade_files=`find ../resources/ -name "*.glade"`
for glade in $glade_files; do
echo "Parsing Glade file $glade"
if [[ -f "$pot" ]]; then
xgettext --package-name="gds-render" --join-existing --keyword=_ -L Glade --sort-output -o "$pot" "$glade"
else
xgettext --package-name="gds-render" --keyword=_ -L Glade --sort-output -o "$pot" "$glade"
fi
done

View File

@@ -0,0 +1,456 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the gds-render package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: gds-render\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-12-16 18:27+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: ../main.c:97
#, c-format
msgid ""
"\n"
"\n"
"Full git commit: %s"
msgstr ""
#: ../main.c:294
msgid " FILE - Convert GDS file <FILE> to graphic"
msgstr ""
#: ../resources/about.glade:10
msgid "!! Replaced during runtime !!"
msgstr ""
#: ../command-line.c:205
#, c-format
msgid "%d reference loops found.\n"
msgstr ""
#: ../main.c:220
msgid "About"
msgstr ""
#: ../main.c:290
msgid "Argument string passed to render lib"
msgstr ""
#: ../resources/main.glade:225
msgid "Automatically color layers"
msgstr ""
#: ../resources/main.glade:255
msgid "Automatically name layers"
msgstr ""
#: ../gds-utils/gds-tree-checker.c:71
#, c-format
msgid "Broken cell list item found in cell %s. Will continue.\n"
msgstr ""
#: ../gds-utils/gds-tree-checker.c:57
#, c-format
msgid "Broken cell list item found. Will continue.\n"
msgstr ""
#: ../output-renderers/cairo-renderer.c:409
#, c-format
msgid "Cairo export finished. It might still be buggy!\n"
msgstr ""
#. Execute
#: ../output-renderers/external-renderer.c:120
msgid "Calling external renderer."
msgstr ""
#: ../gds-render-gui.c:286 ../widgets/conv-settings-dialog.c:291
msgid "Cancel"
msgstr ""
#: ../gds-render-gui.c:244
msgid "Cell"
msgstr ""
#: ../command-line.c:209
#, c-format
msgid "Cell is affected by reference loop. Abort!\n"
msgstr ""
#: ../main.c:284
msgid "Cell to render"
msgstr ""
#: ../command-line.c:215
#, c-format
msgid ""
"Cell was not checked. This should not happen. Please report this issue. Will "
"continue either way.\n"
msgstr ""
#: ../command-line.c:202
#, c-format
msgid "Checking library %s failed.\n"
msgstr ""
#: ../resources/dialog.glade:79
msgid "Configure LaTeX as standalone document"
msgstr ""
#: ../resources/main.glade:109
msgid "Convert selected cell"
msgstr ""
#: ../output-renderers/external-renderer.c:89
#, c-format
msgid ""
"Could not load external library '%s'\n"
"Detailed error is:\n"
"%s\n"
msgstr ""
#: ../output-renderers/latex-renderer.c:373
msgid "Could not open LaTeX output file"
msgstr ""
#: ../command-line.c:195
#, c-format
msgid "Couldn't find cell in first library!\n"
msgstr ""
#: ../command-line.c:81
#, c-format
msgid "Count of renderers %d does not match count of output file names %d\n"
msgstr ""
#: ../main.c:286
msgid "Create PDF Layers (OCG)"
msgstr ""
#: ../main.c:285
msgid "Create standalone TeX"
msgstr ""
#: ../main.c:280
msgid "Divide output coordinates by <SCALE>"
msgstr ""
#: ../resources/layer-widget.glade:62
msgid "Export Layer"
msgstr ""
#: ../output-renderers/cairo-renderer.c:366
#, c-format
msgid "Exporting layer %d to file\n"
msgstr ""
#: ../output-renderers/external-renderer.c:142
msgid "External renderer finished."
msgstr ""
#. This should not happen
#: ../output-renderers/cairo-renderer.c:271
#, c-format
msgid "Fatal error: Cairo Renderer: Could not spawn child process!"
msgstr ""
#: ../resources/main.glade:50
msgid "GDS-Render"
msgstr ""
#: ../gds-render-gui.c:294
msgid "GDSII-Files"
msgstr ""
#: ../resources/dialog.glade:18
msgid "Generate LaTeX/TikZ output"
msgstr ""
#: ../resources/dialog.glade:93
msgid "Generate PDF Layers"
msgstr ""
#: ../output-renderers/latex-renderer.c:253
#, c-format
msgid "Generating cell %s"
msgstr ""
#: ../resources/about.glade:12
msgid "Git Repository"
msgstr ""
#: ../widgets/conv-settings-dialog.c:246
#, c-format
msgid "Height: %.3lf %sm"
msgstr ""
#: ../main.c:321
#, c-format
msgid "Ignored argument: %s"
msgstr ""
#: ../output-renderers/external-renderer.c:106
#, c-format
msgid ""
"Init function not found in library:\n"
"%s\n"
msgstr ""
#: ../output-renderers/cairo-renderer.c:321
#, c-format
msgid "Layer number too high / outside of spec.\n"
msgstr ""
#: ../output-renderers/cairo-renderer.c:369
#, c-format
msgid "Layer outside of spec.\n"
msgstr ""
#: ../widgets/layer-element.c:102
#, c-format
msgid "Layer: %d"
msgstr ""
#: ../gds-render-gui.c:241
msgid "Library"
msgstr ""
#: ../resources/main.glade:68
msgid "Load Mapping"
msgstr ""
#: ../resources/main.glade:73
msgid "Load the current layer configuration from CSV"
msgstr ""
#: ../main.c:116
#, c-format
msgid "Logo could not be displayed: %s\n"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:293
msgid "No layer specification supplied."
msgstr ""
#: ../command-line.c:186
#, c-format
msgid "No library in library list. This should not happen.\n"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:288
msgid "No/invalid output file set."
msgstr ""
#: ../widgets/conv-settings-dialog.c:291
msgid "OK"
msgstr ""
#: ../resources/main.glade:58
msgid "Open GDS2 Database"
msgstr ""
#: ../gds-render-gui.c:287
msgid "Open GDSII"
msgstr ""
#: ../gds-render-gui.c:284
msgid "Open GDSII File"
msgstr ""
#: ../main.c:299
#, c-format
msgid "Option parsing failed: %s\n"
msgstr ""
#: ../widgets/conv-settings-dialog.c:255
#, c-format
msgid "Output Height: %u px"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:283
msgid "Output Renderer not valid."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:304
msgid "Output Renderer: Rendering function broken. This is a bug."
msgstr ""
#. Set the pixel sizes
#: ../widgets/conv-settings-dialog.c:252
#, c-format
msgid "Output Width: %u px"
msgstr ""
#: ../main.c:282
msgid "Output file path. Can be used multiple times."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:298
msgid "Output renderer called without cell to render."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:74
msgid "Output renderer does not define a render_output function!"
msgstr ""
#: ../main.c:283
msgid "Path for Layer Mapping File"
msgstr ""
#: ../main.c:288
msgid ""
"Path to a custom shared object, that implements the necessary rendering "
"functions"
msgstr ""
#: ../output-renderers/external-renderer.c:78
#, c-format
msgid "Path to shared object not set!\n"
msgstr ""
#: ../command-line.c:74
#, c-format
msgid "Please specify renderers and file names\n"
msgstr ""
#: ../command-line.c:104
#, c-format
msgid ""
"Please specify shared object for external renderer. Will ignore this "
"renderer.\n"
msgstr ""
#: ../main.c:277
msgid "Print version"
msgstr ""
#: ../command-line.c:160
#, c-format
msgid "Probably missing argument. Check --help option\n"
msgstr ""
#: ../main.c:219
msgid "Quit"
msgstr ""
#: ../widgets/activity-bar.c:104
msgid "Ready"
msgstr ""
#: ../resources/dialog.glade:33
msgid "Render PDF using Cairographics"
msgstr ""
#: ../resources/dialog.glade:48
msgid "Render SVG using Cairographics (too buggy at the moment)"
msgstr ""
#: ../widgets/conv-settings-dialog.c:293
msgid "Renderer Settings"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:365
msgid "Renderer already started asynchronously"
msgstr ""
#: ../main.c:279
msgid "Renderer to use. Can be used multiple times."
msgstr ""
#: ../output-renderers/cairo-renderer.c:467
msgid "Rendering Cairo Output..."
msgstr ""
#: ../gds-render-gui.c:554
msgid "Rendering cell..."
msgstr ""
#: ../output-renderers/external-renderer.c:98
#, c-format
msgid ""
"Rendering function not found in library:\n"
"%s\n"
msgstr ""
#: ../resources/main.glade:86
msgid "Save Mapping"
msgstr ""
#: ../resources/main.glade:23
msgid "Save the current layer configuration to CSV"
msgstr ""
#: ../main.c:312
#, c-format
msgid "Scale < 1 not allowed. Setting to 1\n"
msgstr ""
#: ../resources/layer-widget.glade:51
msgid "Select Layer Color and Opacity"
msgstr ""
#: ../resources/main.glade:240
msgid "Select all layers for export"
msgstr ""
#: ../output-renderers/cairo-renderer.c:331
#, c-format
msgid "Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n"
msgstr ""
#: ../resources/main.glade:195
msgid "Sort layers ascending"
msgstr ""
#: ../resources/main.glade:210
msgid "Sort layers descending"
msgstr ""
#: ../main.c:212
#, c-format
msgid ""
"There is already an open instance. Will open second window in that "
"instance.\n"
msgstr ""
#: ../main.c:244
#, c-format
msgid ""
"This is gds-render, version: %s\n"
"\n"
"For a list of supported commands execute with --help option.\n"
msgstr ""
#: ../gds-utils/gds-tree-checker.c:188
#, c-format
msgid "Visited cell list should be empty. This is a bug. Please report this.\n"
msgstr ""
#: ../widgets/conv-settings-dialog.c:244
#, c-format
msgid "Width: %.3lf %sm"
msgstr ""
#: ../widgets/activity-bar.c:110
msgid "Working..."
msgstr ""
#: ../main.c:96
msgid ""
"gds-render is a free tool for rendering GDS2 layout files into vector "
"graphics."
msgstr ""
#: ../resources/layer-widget.glade:37
msgid "label"
msgstr ""

View File

@@ -0,0 +1,487 @@
# German translations for gds-render package.
# Copyright (C) 2019 THE gds-render'S COPYRIGHT HOLDER
# This file is distributed under the same license as the gds-render package.
# Mario Hüttel <mario.huettel@gmx.net>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: gds-render\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-12-16 18:27+0100\n"
"PO-Revision-Date: 2019-12-16 22:00+0100\n"
"Last-Translator: Mario Hüttel <mario.huettel@gmx.net>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.2.4\n"
#: ../main.c:97
#, c-format
msgid ""
"\n"
"\n"
"Full git commit: %s"
msgstr ""
"\n"
"\n"
"Vollständiger git-Commit: %s"
#: ../main.c:294
msgid " FILE - Convert GDS file <FILE> to graphic"
msgstr " DATEI - Konvertiere GDS-Datei <DATEI> in Grafik"
#: ../resources/about.glade:10
msgid "!! Replaced during runtime !!"
msgstr "!! Ersetzt zur Laufzeit !!"
#: ../command-line.c:205
#, c-format
msgid "%d reference loops found.\n"
msgstr "%d Referenzschleifen gefunden.\n"
#: ../main.c:220
msgid "About"
msgstr "Info"
#: ../main.c:290
msgid "Argument string passed to render lib"
msgstr "An Render-Bibliothek übergebener Argument-String"
#: ../resources/main.glade:225
msgid "Automatically color layers"
msgstr "Färbe Layer automatisch"
#: ../resources/main.glade:255
msgid "Automatically name layers"
msgstr "Bename Layer automatisch"
#: ../gds-utils/gds-tree-checker.c:71
#, c-format
msgid "Broken cell list item found in cell %s. Will continue.\n"
msgstr "Defektes Listenelement in Zelle %s. Ignoriere.\n"
#: ../gds-utils/gds-tree-checker.c:57
#, c-format
msgid "Broken cell list item found. Will continue.\n"
msgstr "Defektes Zellenelement in Liste gefunden. Ignoriere.\n"
#: ../output-renderers/cairo-renderer.c:409
#, c-format
msgid "Cairo export finished. It might still be buggy!\n"
msgstr "Cairo-Export abgeschlossen. Möglicherweise fehlerhaft!\n"
#. Execute
#: ../output-renderers/external-renderer.c:120
msgid "Calling external renderer."
msgstr "Rufe externen Renderer auf."
#: ../gds-render-gui.c:286 ../widgets/conv-settings-dialog.c:291
msgid "Cancel"
msgstr "Abbruch"
#: ../gds-render-gui.c:244
msgid "Cell"
msgstr "Zelle"
#: ../command-line.c:209
#, c-format
msgid "Cell is affected by reference loop. Abort!\n"
msgstr "Zelle ist von referenzschleife betroffen. Abbruch!\n"
#: ../main.c:284
msgid "Cell to render"
msgstr "Zu rendernde Zelle"
#: ../command-line.c:215
#, c-format
msgid ""
"Cell was not checked. This should not happen. Please report this issue. Will "
"continue either way.\n"
msgstr ""
"Zelle wurde nicht überprüft. Das sollte nicht passieren. Bitte melden Sie "
"dieses Problem. Es wird dennoch fortgefahren.\n"
#: ../command-line.c:202
#, c-format
msgid "Checking library %s failed.\n"
msgstr "Überprüfung von Bibliothek %s fehlgeschlagen.\n"
#: ../resources/dialog.glade:79
msgid "Configure LaTeX as standalone document"
msgstr "Konfiguriere LaTeX als eigenständiges Dokument"
#: ../resources/main.glade:109
msgid "Convert selected cell"
msgstr "Konvertiere ausgewählte Zelle"
#: ../output-renderers/external-renderer.c:89
#, c-format
msgid ""
"Could not load external library '%s'\n"
"Detailed error is:\n"
"%s\n"
msgstr ""
"Externe Bibliothek '%s' konnte nicht geladen werden.\n"
"Detailierter Fehler:\n"
"%s\n"
#: ../output-renderers/latex-renderer.c:373
msgid "Could not open LaTeX output file"
msgstr "LaTeX-Ausgabedatei konnte nicht geöffnet werden"
#: ../command-line.c:195
#, c-format
msgid "Couldn't find cell in first library!\n"
msgstr "Zelle nicht in erster Bibliothek gefunden!\n"
#: ../command-line.c:81
#, c-format
msgid "Count of renderers %d does not match count of output file names %d\n"
msgstr ""
"Anzahl der Renderer %d stimmt nicht mit der Anzahl der angegebenen "
"Ausgabedateinamen %d überein\n"
#: ../main.c:286
msgid "Create PDF Layers (OCG)"
msgstr "Generiere PDF-Layer (OCG)"
#: ../main.c:285
msgid "Create standalone TeX"
msgstr "Generiere eingenständiges TeX"
#: ../main.c:280
msgid "Divide output coordinates by <SCALE>"
msgstr "Dividiere Ausgabekoordinaten durch <SCALE>"
#: ../resources/layer-widget.glade:62
msgid "Export Layer"
msgstr "Exportiere Layer"
#: ../output-renderers/cairo-renderer.c:366
#, c-format
msgid "Exporting layer %d to file\n"
msgstr "Exportiere Layer %d in Datei\n"
#: ../output-renderers/external-renderer.c:142
msgid "External renderer finished."
msgstr "Externer Renderer beendet."
#. This should not happen
#: ../output-renderers/cairo-renderer.c:271
#, c-format
msgid "Fatal error: Cairo Renderer: Could not spawn child process!"
msgstr ""
"Fataler Fehler: Cairo Renderer: Sub-Prozess konnte nicht gestartet werden!"
#: ../resources/main.glade:50
msgid "GDS-Render"
msgstr "GDS-Render"
#: ../gds-render-gui.c:294
msgid "GDSII-Files"
msgstr "GDSII-Dateien"
#: ../resources/dialog.glade:18
msgid "Generate LaTeX/TikZ output"
msgstr "Generiere LaTeX/TikZ Ausgabe"
#: ../resources/dialog.glade:93
msgid "Generate PDF Layers"
msgstr "Generiere PDF Layers"
#: ../output-renderers/latex-renderer.c:253
#, c-format
msgid "Generating cell %s"
msgstr "Generiere Zelle %s"
#: ../resources/about.glade:12
msgid "Git Repository"
msgstr "Git Repository"
#: ../widgets/conv-settings-dialog.c:246
#, c-format
msgid "Height: %.3lf %sm"
msgstr "Höhe: %.3lf %sm"
#: ../main.c:321
#, c-format
msgid "Ignored argument: %s"
msgstr "Ignoriertes Argument: %s"
#: ../output-renderers/external-renderer.c:106
#, c-format
msgid ""
"Init function not found in library:\n"
"%s\n"
msgstr ""
"Init-Funktion nicht in Bibliothek gefunden:\n"
"%s\n"
#: ../output-renderers/cairo-renderer.c:321
#, c-format
msgid "Layer number too high / outside of spec.\n"
msgstr "Layer-Nummer zu hoch / Außerhalb der Spezifikation.\n"
#: ../output-renderers/cairo-renderer.c:369
#, c-format
msgid "Layer outside of spec.\n"
msgstr "Layer außerhalb der Spezifikation\n"
#: ../widgets/layer-element.c:102
#, c-format
msgid "Layer: %d"
msgstr "Layer: %d"
#: ../gds-render-gui.c:241
msgid "Library"
msgstr "Bibliothek"
#: ../resources/main.glade:68
msgid "Load Mapping"
msgstr "Zuordnung laden"
#: ../resources/main.glade:73
msgid "Load the current layer configuration from CSV"
msgstr "Lade die aktuelle Layer-Zuordnung aus einer CSV-Datei"
#: ../main.c:116
#, c-format
msgid "Logo could not be displayed: %s\n"
msgstr "Logo konnte nicht angezeigt werden: %s\n"
#: ../output-renderers/gds-output-renderer.c:293
msgid "No layer specification supplied."
msgstr "Keine Layer-Spezifikation angegeben."
#: ../command-line.c:186
#, c-format
msgid "No library in library list. This should not happen.\n"
msgstr "Keine Bibliothek in Bibliotheksliste. Das sollte nicht passieren.\n"
#: ../output-renderers/gds-output-renderer.c:288
msgid "No/invalid output file set."
msgstr "Keine oder invalide Ausgabedatei angegeben."
#: ../widgets/conv-settings-dialog.c:291
msgid "OK"
msgstr "OK"
#: ../resources/main.glade:58
msgid "Open GDS2 Database"
msgstr "Öffne GDS2 Datenbank"
#: ../gds-render-gui.c:287
msgid "Open GDSII"
msgstr "Öffne GDSII"
#: ../gds-render-gui.c:284
msgid "Open GDSII File"
msgstr "Öffne GDSII-Datei"
#: ../main.c:299
#, c-format
msgid "Option parsing failed: %s\n"
msgstr "Optionsverarbeitung fehlgeschlagen: %s\n"
#: ../widgets/conv-settings-dialog.c:255
#, c-format
msgid "Output Height: %u px"
msgstr "Ausgabehöhe: %u px"
#: ../output-renderers/gds-output-renderer.c:283
msgid "Output Renderer not valid."
msgstr "Ausgaberenderer invalide."
#: ../output-renderers/gds-output-renderer.c:304
msgid "Output Renderer: Rendering function broken. This is a bug."
msgstr ""
"Ausgaberenderer: Render-Funktion defekt. Dies ist ein interner "
"Programmfehler."
#. Set the pixel sizes
#: ../widgets/conv-settings-dialog.c:252
#, c-format
msgid "Output Width: %u px"
msgstr "Ausgabebreite: %u px"
#: ../main.c:282
msgid "Output file path. Can be used multiple times."
msgstr "Ausgabepfad. Kann mehrfach angegeben werden."
#: ../output-renderers/gds-output-renderer.c:298
msgid "Output renderer called without cell to render."
msgstr "Ausgaberenderer ohne zu rendernde Zelle aufgerufen."
#: ../output-renderers/gds-output-renderer.c:74
msgid "Output renderer does not define a render_output function!"
msgstr "Ausgaberenderer definiert keine render_output Funktion!"
#: ../main.c:283
msgid "Path for Layer Mapping File"
msgstr "Pfad zur Lagenzuordnungsdatei"
#: ../main.c:288
msgid ""
"Path to a custom shared object, that implements the necessary rendering "
"functions"
msgstr ""
"Pfad zu einem benutzerdefiniertem Shared-Object, welches die notwendigen "
"Funktionen implementiert"
#: ../output-renderers/external-renderer.c:78
#, c-format
msgid "Path to shared object not set!\n"
msgstr "Kein Pfad zu einem Shared-Object gesetzt!\n"
#: ../command-line.c:74
#, c-format
msgid "Please specify renderers and file names\n"
msgstr "Bitte Renderer und Dateinamen angeben.\n"
#: ../command-line.c:104
#, c-format
msgid ""
"Please specify shared object for external renderer. Will ignore this "
"renderer.\n"
msgstr ""
"Bitte Shares-Object für externen Renderer angeben. Dieser Renderer wird "
"ignoriert.\n"
#: ../main.c:277
msgid "Print version"
msgstr "Zeige Versionsnummer"
#: ../command-line.c:160
#, c-format
msgid "Probably missing argument. Check --help option\n"
msgstr "Vermutlich ein fehlendes Argument. Bitte --help überprüfen\n"
#: ../main.c:219
msgid "Quit"
msgstr "Beenden"
#: ../widgets/activity-bar.c:104
msgid "Ready"
msgstr "Bereit"
#: ../resources/dialog.glade:33
msgid "Render PDF using Cairographics"
msgstr "Rendere PDF mit Cairographics"
#: ../resources/dialog.glade:48
msgid "Render SVG using Cairographics (too buggy at the moment)"
msgstr "Rendere SVG mit Cairographics (Experimentell)"
#: ../widgets/conv-settings-dialog.c:293
msgid "Renderer Settings"
msgstr "Renderer Einstellungen"
#: ../output-renderers/gds-output-renderer.c:365
msgid "Renderer already started asynchronously"
msgstr "Renderer wird bereits asynchron ausgeführt"
#: ../main.c:279
msgid "Renderer to use. Can be used multiple times."
msgstr "Zu nutzender Renderer. Kann mehrfach angegeben werden."
#: ../output-renderers/cairo-renderer.c:467
msgid "Rendering Cairo Output..."
msgstr "Rendere Cairo-Ausgabe..."
#: ../gds-render-gui.c:554
msgid "Rendering cell..."
msgstr "Renderere Zelle..."
#: ../output-renderers/external-renderer.c:98
#, c-format
msgid ""
"Rendering function not found in library:\n"
"%s\n"
msgstr ""
"Render Funktion nicht in Bibliothek gefunden:\n"
"%s\n"
#: ../resources/main.glade:86
msgid "Save Mapping"
msgstr "Zuordnung speichern"
#: ../resources/main.glade:23
msgid "Save the current layer configuration to CSV"
msgstr "Die aktuelle Lagenkonfiguration als CSV-Datei speichern"
#: ../main.c:312
#, c-format
msgid "Scale < 1 not allowed. Setting to 1\n"
msgstr "Skaliereung < 1 nicht erlaubt. Setze auf 1\n"
#: ../resources/layer-widget.glade:51
msgid "Select Layer Color and Opacity"
msgstr "Wähle Layer-Farbe und Transparenz"
#: ../resources/main.glade:240
msgid "Select all layers for export"
msgstr "Wähle alle Layer zum Exporieren"
#: ../output-renderers/cairo-renderer.c:331
#, c-format
msgid "Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n"
msgstr "Größe von Layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n"
#: ../resources/main.glade:195
msgid "Sort layers ascending"
msgstr "Sortiere Layer aufsteigend"
#: ../resources/main.glade:210
msgid "Sort layers descending"
msgstr "Sortiere Layer absteigend"
#: ../main.c:212
#, c-format
msgid ""
"There is already an open instance. Will open second window in that "
"instance.\n"
msgstr ""
"Es ist bereits eine Instanz dieses Programms geöffnet. Es wird ein zweites "
"Fenster in jener Instanz geöffnet.\n"
#: ../main.c:244
#, c-format
msgid ""
"This is gds-render, version: %s\n"
"\n"
"For a list of supported commands execute with --help option.\n"
msgstr ""
"Dies ist gds-render, Version: %s\n"
"\n"
"Für eine Liste der unterstützten Kommandos mit der Option --help ausführen.\n"
#: ../gds-utils/gds-tree-checker.c:188
#, c-format
msgid "Visited cell list should be empty. This is a bug. Please report this.\n"
msgstr ""
"Liste markierter Zellen sollte leer sein. Dies ist ein Fehler. Bitte "
"melden.\n"
#: ../widgets/conv-settings-dialog.c:244
#, c-format
msgid "Width: %.3lf %sm"
msgstr "Breite: %.3lf %sm"
#: ../widgets/activity-bar.c:110
msgid "Working..."
msgstr "Arbeite..."
#: ../main.c:96
msgid ""
"gds-render is a free tool for rendering GDS2 layout files into vector "
"graphics."
msgstr ""
"gds-render ist ein freies Programm, um GDS2-Layouts in Vektorgrafiken zu "
"konvertieren."
#: ../resources/layer-widget.glade:37
msgid "label"
msgstr "label"

View File

@@ -0,0 +1,460 @@
# Japanese translations for gds-render package.
# Copyright (C) 2019 THE gds-render'S COPYRIGHT HOLDER
# This file is distributed under the same license as the gds-render package.
# Mario Hüttel <mario.huettel@gmx.net>, 2019.
#
msgid ""
msgstr ""
"Project-Id-Version: gds-render\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-12-16 18:27+0100\n"
"PO-Revision-Date: 2020-01-16 22:54+0100\n"
"Last-Translator: Mario Hüttel <mario.huettel@gmx.net>\n"
"Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
"Language: ja\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Poedit 2.2.4\n"
#: ../main.c:97
#, c-format
msgid ""
"\n"
"\n"
"Full git commit: %s"
msgstr ""
"\n"
"\n"
"git コミット: %s"
#: ../main.c:294
msgid " FILE - Convert GDS file <FILE> to graphic"
msgstr " ファイル - ファイルを変換する"
#: ../resources/about.glade:10
msgid "!! Replaced during runtime !!"
msgstr "!! ランタイムで代わる !!"
#: ../command-line.c:205
#, c-format
msgid "%d reference loops found.\n"
msgstr "%d 参照ループが見つかりました.\n"
#: ../main.c:220
msgid "About"
msgstr "情報"
#: ../main.c:290
msgid "Argument string passed to render lib"
msgstr "レンダリングに渡されるデタ"
#: ../resources/main.glade:225
msgid "Automatically color layers"
msgstr "レイヤーを自動的に色付けする"
#: ../resources/main.glade:255
msgid "Automatically name layers"
msgstr "レイヤーに自動的に名前を付ける"
#: ../gds-utils/gds-tree-checker.c:71
#, c-format
msgid "Broken cell list item found in cell %s. Will continue.\n"
msgstr "%sのセルで壊れたセルリストアイテムが見つかりました。続けます。\n"
#: ../gds-utils/gds-tree-checker.c:57
#, c-format
msgid "Broken cell list item found. Will continue.\n"
msgstr "壊れたセルリストアイテムが見つかりました。続けます。\n"
#: ../output-renderers/cairo-renderer.c:409
#, c-format
msgid "Cairo export finished. It might still be buggy!\n"
msgstr "Cairoの変換が終了しました.\n"
#. Execute
#: ../output-renderers/external-renderer.c:120
msgid "Calling external renderer."
msgstr "外部レンダラーの実行。"
#: ../gds-render-gui.c:286 ../widgets/conv-settings-dialog.c:291
msgid "Cancel"
msgstr "キャンセル"
#: ../gds-render-gui.c:244
msgid "Cell"
msgstr "セル"
#: ../command-line.c:209
#, c-format
msgid "Cell is affected by reference loop. Abort!\n"
msgstr "このセルに参照ループがあります。アボート!\n"
#: ../main.c:284
msgid "Cell to render"
msgstr "レンダリングされるセル"
#: ../command-line.c:215
#, c-format
msgid ""
"Cell was not checked. This should not happen. Please report this issue. Will "
"continue either way.\n"
msgstr "セルのチェックはしませんでした。これは問題です。\n"
#: ../command-line.c:202
#, c-format
msgid "Checking library %s failed.\n"
msgstr "ライブラリ %s のチェックは失敗しました。\n"
#: ../resources/dialog.glade:79
msgid "Configure LaTeX as standalone document"
msgstr ""
#: ../resources/main.glade:109
msgid "Convert selected cell"
msgstr ""
#: ../output-renderers/external-renderer.c:89
#, c-format
msgid ""
"Could not load external library '%s'\n"
"Detailed error is:\n"
"%s\n"
msgstr ""
#: ../output-renderers/latex-renderer.c:373
msgid "Could not open LaTeX output file"
msgstr ""
#: ../command-line.c:195
#, c-format
msgid "Couldn't find cell in first library!\n"
msgstr ""
#: ../command-line.c:81
#, c-format
msgid "Count of renderers %d does not match count of output file names %d\n"
msgstr ""
#: ../main.c:286
msgid "Create PDF Layers (OCG)"
msgstr ""
#: ../main.c:285
msgid "Create standalone TeX"
msgstr ""
#: ../main.c:280
msgid "Divide output coordinates by <SCALE>"
msgstr ""
#: ../resources/layer-widget.glade:62
msgid "Export Layer"
msgstr ""
#: ../output-renderers/cairo-renderer.c:366
#, c-format
msgid "Exporting layer %d to file\n"
msgstr ""
#: ../output-renderers/external-renderer.c:142
msgid "External renderer finished."
msgstr ""
#. This should not happen
#: ../output-renderers/cairo-renderer.c:271
#, c-format
msgid "Fatal error: Cairo Renderer: Could not spawn child process!"
msgstr ""
#: ../resources/main.glade:50
msgid "GDS-Render"
msgstr ""
#: ../gds-render-gui.c:294
msgid "GDSII-Files"
msgstr ""
#: ../resources/dialog.glade:18
msgid "Generate LaTeX/TikZ output"
msgstr ""
#: ../resources/dialog.glade:93
msgid "Generate PDF Layers"
msgstr ""
#: ../output-renderers/latex-renderer.c:253
#, c-format
msgid "Generating cell %s"
msgstr ""
#: ../resources/about.glade:12
msgid "Git Repository"
msgstr ""
#: ../widgets/conv-settings-dialog.c:246
#, c-format
msgid "Height: %.3lf %sm"
msgstr ""
#: ../main.c:321
#, c-format
msgid "Ignored argument: %s"
msgstr ""
#: ../output-renderers/external-renderer.c:106
#, c-format
msgid ""
"Init function not found in library:\n"
"%s\n"
msgstr ""
#: ../output-renderers/cairo-renderer.c:321
#, c-format
msgid "Layer number too high / outside of spec.\n"
msgstr ""
#: ../output-renderers/cairo-renderer.c:369
#, c-format
msgid "Layer outside of spec.\n"
msgstr ""
#: ../widgets/layer-element.c:102
#, c-format
msgid "Layer: %d"
msgstr ""
#: ../gds-render-gui.c:241
msgid "Library"
msgstr ""
#: ../resources/main.glade:68
msgid "Load Mapping"
msgstr ""
#: ../resources/main.glade:73
msgid "Load the current layer configuration from CSV"
msgstr ""
#: ../main.c:116
#, c-format
msgid "Logo could not be displayed: %s\n"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:293
msgid "No layer specification supplied."
msgstr ""
#: ../command-line.c:186
#, c-format
msgid "No library in library list. This should not happen.\n"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:288
msgid "No/invalid output file set."
msgstr ""
#: ../widgets/conv-settings-dialog.c:291
msgid "OK"
msgstr ""
#: ../resources/main.glade:58
msgid "Open GDS2 Database"
msgstr ""
#: ../gds-render-gui.c:287
msgid "Open GDSII"
msgstr ""
#: ../gds-render-gui.c:284
msgid "Open GDSII File"
msgstr ""
#: ../main.c:299
#, c-format
msgid "Option parsing failed: %s\n"
msgstr ""
#: ../widgets/conv-settings-dialog.c:255
#, c-format
msgid "Output Height: %u px"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:283
msgid "Output Renderer not valid."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:304
msgid "Output Renderer: Rendering function broken. This is a bug."
msgstr ""
#. Set the pixel sizes
#: ../widgets/conv-settings-dialog.c:252
#, c-format
msgid "Output Width: %u px"
msgstr ""
#: ../main.c:282
msgid "Output file path. Can be used multiple times."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:298
msgid "Output renderer called without cell to render."
msgstr ""
#: ../output-renderers/gds-output-renderer.c:74
msgid "Output renderer does not define a render_output function!"
msgstr ""
#: ../main.c:283
msgid "Path for Layer Mapping File"
msgstr ""
#: ../main.c:288
msgid ""
"Path to a custom shared object, that implements the necessary rendering "
"functions"
msgstr ""
#: ../output-renderers/external-renderer.c:78
#, c-format
msgid "Path to shared object not set!\n"
msgstr ""
#: ../command-line.c:74
#, c-format
msgid "Please specify renderers and file names\n"
msgstr ""
#: ../command-line.c:104
#, c-format
msgid ""
"Please specify shared object for external renderer. Will ignore this "
"renderer.\n"
msgstr ""
#: ../main.c:277
msgid "Print version"
msgstr ""
#: ../command-line.c:160
#, c-format
msgid "Probably missing argument. Check --help option\n"
msgstr ""
#: ../main.c:219
msgid "Quit"
msgstr ""
#: ../widgets/activity-bar.c:104
msgid "Ready"
msgstr ""
#: ../resources/dialog.glade:33
msgid "Render PDF using Cairographics"
msgstr ""
#: ../resources/dialog.glade:48
msgid "Render SVG using Cairographics (too buggy at the moment)"
msgstr ""
#: ../widgets/conv-settings-dialog.c:293
msgid "Renderer Settings"
msgstr ""
#: ../output-renderers/gds-output-renderer.c:365
msgid "Renderer already started asynchronously"
msgstr ""
#: ../main.c:279
msgid "Renderer to use. Can be used multiple times."
msgstr ""
#: ../output-renderers/cairo-renderer.c:467
msgid "Rendering Cairo Output..."
msgstr ""
#: ../gds-render-gui.c:554
msgid "Rendering cell..."
msgstr ""
#: ../output-renderers/external-renderer.c:98
#, c-format
msgid ""
"Rendering function not found in library:\n"
"%s\n"
msgstr ""
#: ../resources/main.glade:86
msgid "Save Mapping"
msgstr ""
#: ../resources/main.glade:23
msgid "Save the current layer configuration to CSV"
msgstr ""
#: ../main.c:312
#, c-format
msgid "Scale < 1 not allowed. Setting to 1\n"
msgstr ""
#: ../resources/layer-widget.glade:51
msgid "Select Layer Color and Opacity"
msgstr ""
#: ../resources/main.glade:240
msgid "Select all layers for export"
msgstr ""
#: ../output-renderers/cairo-renderer.c:331
#, c-format
msgid "Size of layer %d%s%s%s: <%lf x %lf> @ (%lf | %lf)\n"
msgstr ""
#: ../resources/main.glade:195
msgid "Sort layers ascending"
msgstr ""
#: ../resources/main.glade:210
msgid "Sort layers descending"
msgstr ""
#: ../main.c:212
#, c-format
msgid ""
"There is already an open instance. Will open second window in that "
"instance.\n"
msgstr ""
#: ../main.c:244
#, c-format
msgid ""
"This is gds-render, version: %s\n"
"\n"
"For a list of supported commands execute with --help option.\n"
msgstr ""
#: ../gds-utils/gds-tree-checker.c:188
#, c-format
msgid "Visited cell list should be empty. This is a bug. Please report this.\n"
msgstr ""
#: ../widgets/conv-settings-dialog.c:244
#, c-format
msgid "Width: %.3lf %sm"
msgstr ""
#: ../widgets/activity-bar.c:110
msgid "Working..."
msgstr ""
#: ../main.c:96
msgid ""
"gds-render is a free tool for rendering GDS2 layout files into vector "
"graphics."
msgstr ""
#: ../resources/layer-widget.glade:37
msgid "label"
msgstr ""

View File

@@ -0,0 +1,34 @@
#!/bin/bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null && pwd )"
cd "$DIR"
if [ -z $1 ]; then
echo "Please specify language code to generate/update"
exit -1
fi
locale="$1"
podir="./po/$locale"
echo "Selected locale: $locale"
mkdir -p "$podir"
pots=`find . -name '*.pot'`
for pot in $pots; do
po=`echo "$podir/${pot%.pot}.po" | sed -e "s/\/.\//\//g"`
echo -n "$po: "
if [ -f "$po" ]; then
echo "update"
msgmerge --update "$po" "$pot"
else
echo "generate"
msginit --input="$pot" --locale="$locale" --output="$po"
fi
done

View File

@@ -1,3 +1,25 @@
project(libversion)
if(NOT WIN32)
string(ASCII 27 Esc)
set(ColorReset "${Esc}[m")
set(ColorBold "${Esc}[1m")
set(Red "${Esc}[31m")
set(Green "${Esc}[32m")
set(Yellow "${Esc}[33m")
set(Blue "${Esc}[34m")
set(Magenta "${Esc}[35m")
set(Cyan "${Esc}[36m")
set(White "${Esc}[37m")
set(BoldRed "${Esc}[1;31m")
set(BoldGreen "${Esc}[1;32m")
set(BoldYellow "${Esc}[1;33m")
set(BoldBlue "${Esc}[1;34m")
set(BoldMagenta "${Esc}[1;35m")
set(BoldCyan "${Esc}[1;36m")
set(BoldWhite "${Esc}[1;37m")
endif()
add_library(version STATIC "version.c")
execute_process(COMMAND bash ./generate-version-string.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -5,6 +27,10 @@ execute_process(COMMAND bash ./generate-version-string.sh
execute_process(COMMAND bash ./generate-git-commit-string.sh
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT)
message("Commit: ${GIT_COMMIT}")
message("Version: ${GIT_VER}")
message("${BoldGreen}Commit: ${GIT_COMMIT}")
message("Version: ${GIT_VER}${ColorReset}")
IF(GIT_VER MATCHES "-dirty")
message("${BoldRed}Build is dirty! Commit your changes before releasing this version!${ColorReset}")
ENDIF(GIT_VER MATCHES "-dirty")
target_compile_definitions(version PRIVATE PROJECT_GIT_VERSION=${GIT_VER} PROJECT_GIT_COMMIT=${GIT_COMMIT})

View File

@@ -17,7 +17,6 @@
* along with GDSII-Converter. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @defgroup version Version Number
* See @ref git-version-num

View File

@@ -37,6 +37,7 @@
*/
#include <gds-render/widgets/activity-bar.h>
#include <glib/gi18n.h>
/** @brief Opaque ActivityBar object. Not viewable outside this source file. */
struct _ActivityBar {
@@ -98,16 +99,15 @@ ActivityBar *activity_bar_new()
return bar;
}
/* TODO: Complete this once the task list is fully implemented */
void activity_bar_set_ready(ActivityBar *bar)
{
gtk_label_set_text(GTK_LABEL(bar->label), "Ready");
gtk_label_set_text(GTK_LABEL(bar->label), _("Ready"));
gtk_spinner_stop(GTK_SPINNER(bar->spinner));
}
void activity_bar_set_busy(ActivityBar *bar, const char *text)
{
gtk_label_set_text(GTK_LABEL(bar->label), (text ? text : "Working..."));
gtk_label_set_text(GTK_LABEL(bar->label), (text ? text : _("Working...")));
gtk_spinner_start(GTK_SPINNER(bar->spinner));
}

View File

@@ -30,6 +30,7 @@
*/
#include <gds-render/widgets/conv-settings-dialog.h>
#include <glib/gi18n.h>
struct _RendererSettingsDialog {
GtkDialog parent;
@@ -102,9 +103,9 @@ static void renderer_settings_dialog_class_init(RendererSettingsDialogClass *kla
oclass->set_property = renderer_settings_dialog_set_property;
oclass->get_property = renderer_settings_dialog_get_property;
properties[PROP_CELL_NAME] = g_param_spec_string("cell-name",
"cell-name",
"Cell name to be displayed in header bar",
properties[PROP_CELL_NAME] = g_param_spec_string(N_("cell-name"),
N_("cell-name"),
N_("Cell name to be displayed in header bar"),
"",
G_PARAM_READWRITE);
g_object_class_install_properties(oclass, PROP_COUNT, properties);
@@ -170,8 +171,11 @@ static gboolean shape_drawer_drawing_callback(GtkWidget *widget, cairo_t *cr, gp
final_scale_value = (width_scale < height_scale ? width_scale : height_scale);
cairo_rectangle(cr, -(double)dialog->cell_width*final_scale_value/2.0, -(double)dialog->cell_height*final_scale_value/2.0,
(double)dialog->cell_width*final_scale_value, (double)dialog->cell_height*final_scale_value);
cairo_rectangle(cr,
-(double)dialog->cell_width * final_scale_value / 2.0,
-(double)dialog->cell_height * final_scale_value / 2.0,
(double)dialog->cell_width * final_scale_value,
(double)dialog->cell_height * final_scale_value);
cairo_stroke(cr);
cairo_restore(cr);
@@ -183,9 +187,9 @@ static double convert_number_to_engineering(double input, const char **out_prefi
const char *selected_prefix = NULL;
double return_val = 0.0;
int idx;
static const char * prefixes[] = {"y", "z", "a", "f", "p", "n", "u", "m", "c", "d", /* < 1 */
"", /* 1 */
"h", "k", "M", "G", "T", "P", "E", "Z", "Y"}; /* > 1 */
static const char * const prefixes[] = {"y", "z", "a", "f", "p", "n", "u", "m", "c", "d", /* < 1 */
"", /* 1 */
"h", "k", "M", "G", "T", "P", "E", "Z", "Y"}; /* > 1 */
static const double scale[] = {1E-24, 1E-21, 1E-18, 1E-15, 1E-12, 1E-9, 1E-6, 1E-3, 1E-2, 1E-1,
1,
1E2, 1E3, 1E6, 1E9, 1E12, 1E15, 1E18, 1E21, 1E24};
@@ -193,7 +197,7 @@ static double convert_number_to_engineering(double input, const char **out_prefi
/* If pointer is invalid, return NaN */
if (!out_prefix)
return 0.0 / 0.0;
return (0.0 / 0.0);
/* Start with the 2nd smallest prefix */
for (idx = 1; idx < prefix_count; idx++) {
@@ -237,18 +241,18 @@ static void renderer_settings_dialog_update_labels(RendererSettingsDialog *self)
width_engineering = convert_number_to_engineering(width_meters, &width_prefix);
height_engineering = convert_number_to_engineering(height_meters, &height_prefix);
snprintf(default_buff, sizeof(default_buff), "Width: %.3lf %sm", width_engineering, width_prefix);
snprintf(default_buff, sizeof(default_buff), _("Width: %.3lf %sm"), width_engineering, width_prefix);
gtk_label_set_text(self->x_label, default_buff);
snprintf(default_buff, sizeof(default_buff), "Height: %.3lf %sm", height_engineering, height_prefix);
snprintf(default_buff, sizeof(default_buff), _("Height: %.3lf %sm"), height_engineering, height_prefix);
gtk_label_set_text(self->y_label, default_buff);
scale = gtk_range_get_value(GTK_RANGE(self->scale));
/* Set the pixel sizes */
snprintf(default_buff, sizeof(default_buff), "Output Width: %u px",
snprintf(default_buff, sizeof(default_buff), _("Output Width: %u px"),
(unsigned int)((double)self->cell_width / scale));
gtk_label_set_text(self->x_output_label, default_buff);
snprintf(default_buff, sizeof(default_buff), "Output Height: %u px",
snprintf(default_buff, sizeof(default_buff), _("Output Height: %u px"),
(unsigned int)((double)self->cell_height / scale));
gtk_label_set_text(self->y_output_label, default_buff);
}
@@ -284,9 +288,9 @@ static void renderer_settings_dialog_init(RendererSettingsDialog *self)
self->x_output_label = GTK_LABEL(gtk_builder_get_object(builder, "x-output-label"));
self->y_output_label = GTK_LABEL(gtk_builder_get_object(builder, "y-output-label"));
gtk_dialog_add_buttons(dialog, "Cancel", GTK_RESPONSE_CANCEL, "OK", GTK_RESPONSE_OK, NULL);
gtk_dialog_add_buttons(dialog, _("Cancel"), GTK_RESPONSE_CANCEL, _("OK"), GTK_RESPONSE_OK, NULL);
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(dialog)), box);
gtk_window_set_title(GTK_WINDOW(self), "Renderer Settings");
gtk_window_set_title(GTK_WINDOW(self), _("Renderer Settings"));
g_signal_connect(self->radio_latex, "toggled", G_CALLBACK(latex_render_callback), (gpointer)self);
g_signal_connect(G_OBJECT(self->shape_drawing),
@@ -308,9 +312,9 @@ RendererSettingsDialog *renderer_settings_dialog_new(GtkWindow *parent)
RendererSettingsDialog *res;
res = RENDERER_SETTINGS_DIALOG(g_object_new(RENDERER_TYPE_SETTINGS_DIALOG, NULL));
if (res && parent) {
if (res && parent)
gtk_window_set_transient_for(GTK_WINDOW(res), parent);
}
return res;
}
@@ -322,13 +326,12 @@ void renderer_settings_dialog_get_settings(RendererSettingsDialog *dialog, struc
settings->scale = gtk_range_get_value(GTK_RANGE(dialog->scale));
/* Get active radio button selection */
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE) {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_latex)) == TRUE)
settings->renderer = RENDERER_LATEX_TIKZ;
} else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_pdf)) == TRUE) {
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_pdf)) == TRUE)
settings->renderer = RENDERER_CAIROGRAPHICS_PDF;
} else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg)) == TRUE) {
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->radio_cairo_svg)) == TRUE)
settings->renderer = RENDERER_CAIROGRAPHICS_SVG;
}
settings->tex_pdf_layers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->layer_check));
settings->tex_standalone = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->standalone_check));

View File

@@ -37,6 +37,7 @@
*/
#include <gds-render/widgets/layer-element.h>
#include <glib/gi18n.h>
G_DEFINE_TYPE(LayerElement, layer_element, GTK_TYPE_LIST_BOX_ROW)
@@ -54,6 +55,7 @@ static void layer_element_constructed(GObject *obj)
static void layer_element_class_init(LayerElementClass *klass)
{
GObjectClass *oclass = G_OBJECT_CLASS(klass);
oclass->dispose = layer_element_dispose;
oclass->constructed = layer_element_constructed;
}
@@ -62,6 +64,7 @@ static void layer_element_init(LayerElement *self)
{
GtkBuilder *builder;
GtkWidget *glade_box;
builder = gtk_builder_new_from_resource("/gui/layer-widget.glade");
glade_box = GTK_WIDGET(gtk_builder_get_object(builder, "box"));
gtk_container_add(GTK_CONTAINER(self), glade_box);
@@ -86,7 +89,7 @@ const char *layer_element_get_name(LayerElement *elem)
return gtk_entry_get_text(elem->priv.name);
}
void layer_element_set_name(LayerElement *elem, const char* name)
void layer_element_set_name(LayerElement *elem, const char *name)
{
gtk_entry_set_text(elem->priv.name, name);
}
@@ -96,7 +99,7 @@ void layer_element_set_layer(LayerElement *elem, int layer)
GString *string;
string = g_string_new_len(NULL, 100);
g_string_printf(string, "Layer: %d", layer);
g_string_printf(string, _("Layer: %d"), layer);
gtk_label_set_text(elem->priv.layer, (const gchar *)string->str);
elem->priv.layer_num = layer;
g_string_free(string, TRUE);
@@ -139,8 +142,9 @@ void layer_element_set_dnd_callbacks(LayerElement *elem, struct layer_element_dn
return;
/* Setup drag and drop */
gtk_style_context_add_class (gtk_widget_get_style_context(GTK_WIDGET(elem)), "row");
gtk_drag_source_set(GTK_WIDGET(elem->priv.event_handle), GDK_BUTTON1_MASK, data->entries, data->entry_count, GDK_ACTION_MOVE);
gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(elem)), "row");
gtk_drag_source_set(GTK_WIDGET(elem->priv.event_handle), GDK_BUTTON1_MASK,
data->entries, data->entry_count, GDK_ACTION_MOVE);
g_signal_connect(elem->priv.event_handle, "drag-begin", G_CALLBACK(data->drag_begin), NULL);
g_signal_connect(elem->priv.event_handle, "drag-data-get", G_CALLBACK(data->drag_data_get), NULL);
g_signal_connect(elem->priv.event_handle, "drag-end", G_CALLBACK(data->drag_end), NULL);